data.table 使用 ifelse() 进行逐行计算

问题描述 投票:0回答:1

我有一个包含以下四列的 data.table:

col1 = as.numeric(0),
col2 = as.numeric(0),
col3 = as.numeric(0),
col4 = as.numeric(0)

如果出现

!is.na(df$col2) OR df$col2 != 0
列 4 = 列 2 + 列 3 否则 列4 = 列1 + 列3

在闪亮应用程序的框架中,我使用了嵌套的 ifelse() 语句来执行此条件计算。在这方面,我尝试了以下两个版本的代码,但 col4 在这两种情况下都没有得到结果。

有人可以告诉我正确的方法吗?

我经历了几个SO问题,但无法有效地弄清楚如何在我的案例中使用他们的解决方案。如果这个论坛中有类似的问题并有相关的解决方案,那么我会得到它并放弃我自己的问题。

      #The 1st version of my code:

      library(shiny)
      library(shinydashboard)
      library(rhandsontable)
      library(data.table)

      DF <- data.table(
               col1 = as.numeric(0),
               col2 = as.numeric(0),
               col3 = as.numeric(0),
               col4 = as.numeric(0),
               stringsAsFactors = FALSE
          )

      ui <- fluidPage(
        dashboardPage(
          dashboardHeader(),
          dashboardSidebar(        
            menuItem("Calculation", tabName = "calc")
          ),
          dashboardBody(
            tabItems(
              tabItem(tabName = "calc",
                      rHandsontableOutput("table")
              )
            )
          )
        )
      )

      server = function(input, output, session) {

        data <- reactiveValues()
 
        observe({ data$df <- as.data.table(DF) })

        observeEvent(input$table, {
          data$df[[4]] <- ifelse(
                        !is.na(data$df[[2]]) | data$df[[2]] != 0,
                        data$df[[2]] + data$df[[3]],
                        ifelse(
                          data$df[[2]]==NA | data$df[[2]] == 0,
                          data$df[[1]] + data$df[[3]],
                          NULL
              )
           )
        })

        output$table <- renderRHandsontable({
          rhandsontable(data$df)
        })
      }

      shinyApp(ui, server)


    `#The 2nd version of mycode:`


      library(shiny)
      library(shinydashboard)
      library(rhandsontable)
      library(data.table)


      DF <- data.table(
               col1 = as.numeric(0),
               col2 = as.numeric(0),
               col3 = as.numeric(0),
               col4 = as.numeric(0),
               stringsAsFactors = FALSE
            )

      ui <- fluidPage(
        dashboardPage(
          dashboardHeader(),
          dashboardSidebar(        
            menuItem("Calculation", tabName = "calc")
          ),
          dashboardBody(
            tabItems(
              tabItem(tabName = "calc",
                  rHandsontableOutput("table")
              )
            )
          )
        )
      )

      server = function(input, output, session) {

        data <- reactiveValues()

        observe({ data$df <- as.data.table(DF) })

        output$table <- renderRHandsontable({
          data$df[, col4 := ifelse(!is.na(data$df[[2]]) | data$df[[2]] != 0,
                           data$df[[2]] + data$df[[3]],
                             ifelse(data$df[[2]]== NA | data$df[[2]] == 0,
                                    data$df[[1]] + data$df[[3]],
                                    NULL))]
          rhandsontable(data$df)
        })
      }

      shinyApp(ui, server)
r if-statement shiny data.table calculation
1个回答
0
投票

col4
未更新的问题是,在您的代码中,由
reactiveValue
定义的
data$df
一旦初始化为
as.data.table(DF)
(其中
DF
是您的初始数据帧),然后就永远不会使用当前数据帧进行更新用户从
RHandsontable
提交的值。您可以使用
hot_to_r
来完成此操作,如下所示,即
data$df <- as.data.frame(hot_to_r(input$table))

此处无关,但您的

if
条件没有意义。如果您说
!is.na(df$col2) OR df$col2 != 0
以及例如
df$col2
NA
,那么第二部分中的
or
会导致
NA
,这会破坏第4列中的输出。您可能需要这里的
&
或其他东西(下面我使用了
&
,请注意
FALSE & NA
计算为
FALSE
FALSE | NA
计算为
NA
)。

library(shiny)
library(shinydashboard)
library(rhandsontable)
library(data.table)

DF <- data.table(
  col1 = as.numeric(0),
  col2 = as.numeric(0),
  col3 = as.numeric(0),
  col4 = as.numeric(0),
  stringsAsFactors = FALSE
)

ui <- fluidPage(
  dashboardPage(
    dashboardHeader(),
    dashboardSidebar(        
      menuItem("Calculation", tabName = "calc")
    ),
    dashboardBody(
      tabItems(
        tabItem(tabName = "calc",
                rHandsontableOutput("table")
        )
      )
    )
  )
)

server = function(input, output, session) {
  
  data <- reactiveValues(df = as.data.table(DF))
  
  observeEvent(input$table, {
    data$df <- as.data.frame(hot_to_r(input$table))
    
    data$df[[4]] <- ifelse(
      !is.na(data$df[[2]]) && data$df[[2]] != 0,
      data$df[[2]] + data$df[[3]],
      data$df[[1]] + data$df[[3]]
    )
  })
  
  output$table <- renderRHandsontable({
    rhandsontable(data$df)
  })
}

shinyApp(ui, server)
© www.soinside.com 2019 - 2024. All rights reserved.