【发布时间】:2020-02-08 03:36:05
【问题描述】:
在 Shiny 中,使用updateSelectInput() 实现条件过滤器(其中过滤器 B 的可选选择取决于过滤器 A)是许多问题(如 here)的公认解决方案。然而,在实现它时,我经常遇到输出对象加载两次,这在小数据集上不可见,但在真正的大数据集上是可见的。
我在下面的iris 数据集上生成了一个最小示例,Sys.sleep() 表示显示双重负载的耗时操作。
防止这种情况发生的最佳方法是什么?我觉得在某个地方有一个好的 req() 应该可以解决问题,但我不知道如何以及在哪里。
library(shiny)
library(dplyr)
ui <- fluidPage(
selectInput("species", "Species", choices=levels(iris$Species)),
selectInput("petal_width", "Petal Width", ""),
tableOutput("iris_table")
)
server <- function(session, input, output) {
output$iris_table <- renderTable({
Sys.sleep(2) # to show the double loading time
iris %>%
filter(Species == input$species,
Petal.Width == input$petal_width)
})
petal_width_options <- reactive({
iris$Petal.Width[iris$Species == input$species]
})
observe({
updateSelectInput(session, "petal_width", choices = petal_width_options())
})
}
shinyApp(ui, server)
编辑:
更具体地说:如果您运行应用程序并更改顶部(物种)选择器的值,例如对于 versicolor,可能的底部选择器(花瓣宽度)选项会相应改变,这就是我想要的。
您还可以看到输出表将加载(渲染可能是一个更好的术语)两次。我假设它这样做是因为首先更新物种选择器的执行顺序,而不是表一次(在这种情况下暂时导致一个空表)和底部选择器大约同时一次,然后表再次调整到新的底部选择器值。我希望表格只在两个选择器值都完成更新时呈现一次。
【问题讨论】:
-
我不确定我是否理解您所说的双重加载问题。你能更明确地描述你想要的行为吗?
-
@MrFlick 已编辑以更明确地描述预期行为
-
你反对“画桌”按钮吗?由于
iris_table既依赖于species和petal_width,但petal_width也依赖于species,因此存在级联反应元素解析,导致iris_table渲染两次。一个按钮将允许在呈现表格之前进行两个更改。这里讨论了一个概念上类似的问题:stackoverflow.com/questions/31161372/… -
@Greg 按钮不是我想要的。我正在尝试将 Shiny over Tableau 推广到我的公司,因此期望输出元素在没有按钮的情况下发生反应性变化(如在 Tableau 中)。 TimTeaFan 的解决方案完美运行。
标签: r shiny shiny-reactivity