【发布时间】:2020-10-30 19:00:08
【问题描述】:
我希望能够在闪亮的 UI 输入中根据用户之前的选择进行自我更新。所以在下面的例子中,预期的行为是用户从cyl、vs或carb中选择
- 过滤数据集
mtcars用于创建绘图,即用户将绘图调整为过滤条件和 - 更新其他过滤器中的剩余输入选项,以便与基于现有过滤器的剩余选项相对应。
这是我尝试过的:
library(shiny)
library(dplyr)
library(plotly)
data("mtcars")
# create ui
ui <- fluidPage(
fluidRow(
box(
title = "Filter",
uiOutput(outputId = "cyl_dynamic_input"),
uiOutput(outputId = "vs_dynamic_input"),
uiOutput(outputId = "carb_dynamic_input")
),
box(
title = "Plot of mtcars",
plotlyOutput("carplot")
)
),
)
# create server
server <- function(input, output, session) {
# create reactive filters of the mtcars table
mtcars.reactive <-
reactive({
mtcars %>%
filter(mpg %in% input$cyl_input_rendered &
vs %in% input$vs_input_rendered &
carb %in% input$carb_input_rendered
)})
## create rendered inputs
# for cyl
output$cyl_dynamic_input <- renderUI({
pickerInput(inputId = "cyl_input_rendered",
label = "CYL",
choices = unique(mtcars$cyl),
multiple = T,
selected = mtcars.reactive()$cyl,
options = list(
`actions-box` = TRUE,
`selected-text-format`= "count",
`count-selected-text` = "{0} out of {1} cyl selected"
))
})
# for vs
output$vs_dynamic_input <- renderUI({
pickerInput(inputId = "vs_input_rendered",
label = "VS",
choices = unique(mtcars$vs),
multiple = T,
selected = mtcars.reactive()$vs,
options = list(
`actions-box` = TRUE,
`selected-text-format`= "count",
`count-selected-text` = "{0} out of {1} vs selected"
))
})
# for carb
output$carb_dynamic_input <- renderUI({
pickerInput(inputId = "carb_input_rendered",
label = "CARB",
choices = unique(mtcars$carb),
multiple = T,
selected = mtcars.reactive()$carb,
options = list(
`actions-box` = TRUE,
`selected-text-format`= "count",
`count-selected-text` = "{0} out of {1} carb selected"
))
})
## create the plot output
# Start Barplot Emissionen here
output$carplot<-
renderPlotly({
# create plot
plot<-ggplot(mtcars.reactive(), aes(wt, mpg))+
geom_point()
# convert to plotly
ggplotly(plot)
})
}
shinyApp(ui, server)
我的猜测是这不起作用,因为mtcarstable 的过滤器引用了渲染的输入,反之亦然,这会以某种方式创建一个空的信息循环
我已经看过official Shiny documentation,它也提供了一些background information,但整个主题对于初学者来说并不是很直观。这是一个similar question,但它不是完全可重现的。
【问题讨论】:
-
要根据另一个
pickerInput的选定值更改选定的值,您需要在响应于定义pickerInput。没有必要使用uiOutput/renderUI。 -
您还必须确保逻辑不会互锁:如果用户取消选择所有内容,则可能无法返回,因为 mtcars.reactive() 将是空的,因此所有唯一的( ...) 选择可能性也将变为空
-
谢谢你们两位的cmets。我可以解决第一个问题,它想稍后再提供答案。但是@Waldi 关于联锁的第二条评论不是。您会建议如何解决空 mtcars 取消选择所有的问题?
-
您可能需要在 pickerInputs 之间保持层次结构:第一个完全免费,第二个取决于第一个,第三个取决于第一个和第二个。不像你最初的愿望那样开放,但更容易理解/处理