Shiny应用中%in%运算符在响应式语句中不符合预期(版本兼容问题)
问题原因
当selectizeInput开启multiple = TRUE后,input$carb会成为字符向量。原代码中if(input$carb == "All")在多选场景下会生成长度大于1的逻辑向量,而if语句要求条件必须是单个布尔值,这就触发了“条件长度大于1”的报错。Shiny 1.7.3对这类逻辑判断的校验更严格,因此旧版本可运行的代码在新版本中出现了错误。
解决方案
将判断条件从input$carb == "All"改为"All" %in% input$carb——无论input$carb是单个值还是多值向量,该表达式都会返回单个布尔值,完全符合if语句的要求。同时该逻辑会优先处理“All”选项,避免用户同时选中“All”和其他选项时的冲突。
修改后的完整代码:
library(shiny) library(dplyr) data <- mtcars ui <- fluidPage( fluidRow( column(width = 4, wellPanel( selectizeInput("carb", "carb:", c("All", sort(unique(data$carb))), selected = "All", multiple = TRUE, options = list('plugins' = list('remove_button'), 'create' = TRUE, 'persist' = FALSE)) )), column(width = 8, wellPanel(tableOutput("table"))) ) ) server <- function(input,output,session){ process <- reactive({ req(input$carb) if("All" %in% input$carb){ data } else { data %>% dplyr::filter(carb %in% input$carb) } }) output$table <- renderTable({process()}) } shinyApp(ui = ui, server = server)
可选优化
如果要避免用户同时选中“All”和其他选项的情况,可以添加响应式逻辑自动修正选中项:
server <- function(input,output,session){ observeEvent(input$carb, { # 选中All且同时有其他选项时,仅保留All if("All" %in% input$carb && length(input$carb) > 1){ updateSelectizeInput(session, "carb", selected = "All") } # 取消All时,自动移除All的选中状态 else if(!("All" %in% input$carb)){ updateSelectizeInput(session, "carb", choices = c("All", sort(unique(data$carb)))) } }, ignoreInit = TRUE) process <- reactive({ req(input$carb) if("All" %in% input$carb){ data } else { data %>% dplyr::filter(carb %in% input$carb) } }) output$table <- renderTable({process()}) }
内容的提问来源于stack exchange,提问作者mdc690
相关产品推荐
相关产品推荐

