如何根据来自 renderUI 的输入对数据进行子集化

问题描述

我正在尝试根据来自 renderUI 的输入对我的数据进行子集化。然后将这些数据传递给 observe 块中的进一步工作。

下面是一个示例,其中服务器代码存在问题。我在识别 if 子句的输入时遇到了困难 - 或者更准确地说,它以 NULL 开头,然后 "Every row" 中的 input 被识别。如果我在下面的 carbData() 中取消注释 observe,我会收到以下错误。如果我将子集移动到 observe 环境中,也会收到类似的错误

收听http://127.0.0.1:7400
NULL ### 来自 check()
警告:if 中的错误:参数长度为零
61:reactive:carbData [#9]
45:碳水化合物数据
44:[#17]
1:运行应用

这是由于使用 renderUI 的某些延迟评估造成的吗?如果是这样,或者我该如何解决

我的代码

server <- function(input,output) {

    amData <- reactive({ mtcars[am %in% input$am,] }) 
    output$gear <- renderUI({ selectInput("Gear","GEAR",choices=unique(amData()[,"gear"]),selected=4 ) })
    
    gearData <- reactive({ amData()[gear %in% input$Gear,] }) 
    output$carb <- renderUI({ selectInput("Carb","CARB",choices=c("Every row",unique(gearData()[,"carb"])),selected="Every row") })
    
    carbData <-  reactive({ if(input$Carb %in% "Every row") gearData() else gearData()[ carb %in% input$Carb ] }) #### PROBLEM
    
    # Some text where it can be seen that input$Carb  is initially NULL
    check <-  reactive({ p <- input$Carb; print(p) }) 
    
    observe({ 
      check(); 
        
      # problems with if clause in both of these:
      # carbData() 
        
      # Moving the data subset inside `observe` doesn't help
      # df <- if(input$Carb %in% "Every row") gearData() else gearData()[ carb %in% input$Carb ]
      })
}

以及允许它运行的其余代码

library(shiny)
library(shinydashboard)

data(mtcars); data.table::setDT(mtcars)

ui <- dashboardPage(
  dashboardHeader(),dashboardSidebar(
   sidebarMenu(
       selectInput("am","AM",unique(mtcars$am),selected = "0"),uIoUtput("gear"),uIoUtput("carb")
       )),dashboardBody())

runApp(shinyApp(ui,server))

解决方法

我有点不确定这个问题是否已经结束。但是,我花了大量时间编辑您的代码来定位问题。

我使用 tibbles 而不是 data.table 因为我不熟悉语法。到目前为止@stefan 是完全正确的,req(input$Carb) 会为您解除烦恼。

gear %in% input$Gear 有效而 input$Carb %in% "Every row" 无效的原因是 reactive-hierachy 不支持 input$Carb,而 null在启动时,您实际上是在测试 NULL %in% "Every Row"gear 存在于应用启动时的构造中。

正如我确定您知道的那样,这与 input$Carb %in% "NULL"NULL 不同。

这是我玩过的你的代码,

server <- function(input,output) {
        amData <- reactive({
                mtcars %>% filter(am %in% input$am)
                
                
        })
        
        gearData <- reactive({
                amData() %>% filter(gear %in% input$Gear)
                
                
        })
        
        
        output$gear <- renderUI({
                selectInput("Gear","GEAR",choices = unique(amData()[,"gear"]),selected = 4)
        })
        
        
        output$carb <- renderUI({
                selectInput(
                        "Carb","CARB",choices = c("Every row",unique(gearData()[,"carb"])),selected = "Every row"
                )
        })
        
        carbData <-
                reactive({
                        
                        req(input$Carb)
                        
                        if (input$Carb %in% "Every row")
                                gearData()
                        else
                                gearData() %>% filter(carb %in% input$Carb)
                }) #### PROBLEM
        
        # Some text where it can be seen that input$Carb  is initially NULL
        check <-  reactive({
                p <- input$Carb
                print(p)
        })
        
        observe({
                check()
                
                
                # problems with if clause in both of these:
                carbData()
                
        })
}