闪亮的 SelectInput 和 SelectizeInput

Posted

技术标签:

【中文标题】闪亮的 SelectInput 和 SelectizeInput【英文标题】:Shiny SelectInput and SelectizeInput 【发布时间】:2019-01-24 16:35:42 【问题描述】:

我将 Shiny 库更新到 1.1.0 版,我注意到 selectInput/selectizeInput 和 observeEvent/eventReactive 有一些非常奇怪的行为。

    当我按退格键并清除下拉菜单的内容时出现问题。在之前的 Shiny 版本中,退格键与 eventReactive 相结合,反应式表达式不会计算(我猜它会将其视为 NULL)观察,反应式会计算所需的值。

    req() 的行为也很奇怪,在下面的示例 1 中,如果我们按下退格键并清除输入,则会触发 renderTable,但当 req(input$variable) 为空时,表格会消失。在以前的版本中,如果 Shiny 我相信桌子会保持不变。

复制代码:

示例 1

shinyApp(
  ui = fluidPage(
    selectizeInput("variable", "Variable:",
                c("Cylinders" = "cyl",
                  "Transmission" = "am",
                  "Gears" = "gear")),
    tableOutput("data")
  ),
  server = function(input, output) 
    observeEvent(input$variable,
      cat("Printing: ",input$variable,"\n")
    )

    output$data <- renderTable(
      req(input$variable)
      Sys.sleep(2)
      mtcars[, c("mpg", input$variable), drop = FALSE]
    , rownames = TRUE)
  
)

示例 2

这看起来不错,但如果您注意到按下退格键时仍会调用 renderTable。如果这是一个昂贵的计算,那将是不受欢迎的行为。

    shinyApp(
  ui = fluidPage(
    selectInput("variable", "Variable:",
                   c("Cylinders" = "cyl",
                     "Transmission" = "am",
                     "Gears" = "gear")),
    tableOutput("data")
  ),
  server = function(input, output) 
    observeEvent(input$variable,
      cat("Printing: ",input$variable,"\n")
    )

    output$data <- renderTable(
      req(input$variable)
      Sys.sleep(2)
      mtcars[, c("mpg", input$variable), drop = FALSE]
    , rownames = TRUE)
  
)

我想要的行为:当按下退格键清除菜单时,observeEvents 和 eventReactive 没有被触发。

【问题讨论】:

【参考方案1】:

当前行为似乎触发了退格事件,但输入值保持不变。此行为实际上可能是 javascript 函数 Shiny.onInputChange 更新时发生的意外更改。 NEWS on shinys github site 在 1.1 版中声明以下内容。

新功能

[...]

对(未记录但广泛使用的)JavaScript 函数 Shiny.onInputChange(name, value) 进行了两项更改。首先,我们将函数名更改为Shiny.setInputValue(但不用担心——旧的函数名将继续有效)。其次,到现在,所有对Shiny.onInputChange(inputId, value) 的调用都已“去重”;也就是说,只要将输入设置为它已有的相同值,该设置就会被忽略。使用 Shiny v1.1,您现在可以添加一个选项对象作为第三个参数:Shiny.setInputValue("name", value, priority: "event")。当优先级选项设置为“事件”时,Shiny 将始终发送值并触发响应,无论是否重复。

selectInput 的当前版本似乎利用了这个新的priority: "event" 选项,但这只是猜测。

解决方法

您可以通过自己对输入进行重复数据删除来调整您的服务器代码以正确处理这种新行为。

dedupedValue <- reactiveVal()
observe( dedupedValue(input$value) )

然后在服务器代码的其余部分使用dedupedValue() 而不是input$value。这也适用于旧版本的闪亮。

注意:如果您尝试在上述代码中使用reactive 而不是observe,它将不起作用。

长期解决方案

也许最好在闪亮的开发人员查看your GitHub issue 之前搁置这个问题。如上所述,造成这种情况的原因可能是闪亮的 JavaScript 方面的接口更改。如果这确实造成了代码破坏性更改,我相信开发人员会提供修复以确保向后兼容。

关于req

这基本上与手头的问题无关,但提出了您的问题:如果您希望req 在条件不是“真实”的情况下重新训练旧输出,您应该将其称为

req(condition, cancelOuput = TRUE)

【讨论】:

以上是关于闪亮的 SelectInput 和 SelectizeInput的主要内容,如果未能解决你的问题,请参考以下文章

在闪亮的 R 中使用 selectInput 来选择和过滤行,而不是选择列

闪亮的 selectInput 'Select All' 层次结构

如何从闪亮的selectInput中删除“”?

来自列 DF 的闪亮 selectInput

在闪亮中将 selectInput 与 sliderInput 链接起来

闪亮的 renderUI selectInput 返回 NULL