我想根据菜单选项缩小显示给用户的菜单选项。因此,如果用户选择4中的"cyl",他们会看到选中的"4"框,然后只有基于该过滤器可供选择的"gear"复选框可用。
library(shiny)
library(data.table)
server = function(input, output) {
filtered_data <- reactive({
data <- as.data.table(mtcars)
if (!is.null(input$cyl)) {data <- data[input$cyl == cyl ]}
if (!is.null(input$gear)){data <- data[input$gear == gear]}
return(data)
})
output$table <- renderTable(filtered_data())
output$cyl_choices <- renderUI({
unique_cyl <- unique(filtered_data()$cyl)
unique_gear <- unique(filtered_data()$gear)
return(tagList(
checkboxGroupInput("cyl", "Number of cylinders:", unique_cyl),
checkboxGroupInput("gear", "Gear:", unique_gear)
)
)
}
)
}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
uiOutput("cyl_choices")
),
mainPanel(
tableOutput("table")
)
)
)
shinyApp(ui, server)
我在R Shiny中发现的是菜单立即将"Cyl"的复选框重置为空。
[编辑]
更一般地说,我希望在任何一个框中都有一个选项,以限制剩下的框中的选项。当我使用下面的代码根据建议进行第二次选择时,一切都重置了。
library(shiny)
library(data.table)
data <- as.data.table(mtcars)[,
c("cyl", "vs", "am", "gear", "carb") :=
lapply(.SD, as.integer),
.SDcols = c("cyl", "vs", "am", "gear", "carb")]
`%|%` <- function(a, b) {
if (is.null(a)) b else a
}
menu <- function(x){
sort(unique(x))
}
server <- function(input, output, session) {
get_cyl <- reactive({
input$cyl %|% data[, menu(cyl)]
})
get_gear <- reactive({
input$gear %|% data[,menu(gear)]
})
get_carb <- reactive({
input$carb %|% data[,menu(carb)]
})
get_cyl_choices <- reactive({
data[gear %in% get_gear() &
carb %in% get_carb(),
unique(cyl)]
})
get_gear_choices <- reactive({
data[cyl %in% get_cyl() &
carb %in% get_carb(),
unique(gear)]
})
get_carb_choices <- reactive({
data[cyl %in% get_cyl() &
gear %in% get_gear(),
unique(carb)]
})
output$table <- renderTable({
data[cyl %in% get_cyl() &
gear %in% get_gear() &
carb %in% get_carb()
]
})
observeEvent(get_gear_choices(), {
updateCheckboxGroupInput(session,
"gear",
choices = get_gear_choices())
})
observeEvent(get_cyl_choices(), {
updateCheckboxGroupInput(session,
"cyl",
choices = get_cyl_choices())
})
observeEvent(get_carb_choices(), {
updateCheckboxGroupInput(session,
"carb",
choices = get_carb_choices())
})
}
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
checkboxGroupInput("cyl", "Cyl:", data[, menu(cyl)]),
checkboxGroupInput("gear", "Gear:", data[, menu(gear)]),
checkboxGroupInput("carb", "Carb:", data[, menu(carb)])
),
mainPanel(
tableOutput("table")
)
)
)
shinyApp(ui, server)
2条答案
按热度按时间dced5bon1#
问题是,一旦
cyl
发生变化,您就重新呈现gear
输入,这反过来又会改变filtered_data
,而filtered_data
又会改变您的输入,因此一切都被重置。话虽如此,我还是会将这两个
checkboxGroupInputs
分开,使用update*
,而不是重新渲染(但这是一个品味问题,我觉得只更改一个方面比重新渲染整个输入“更便宜”,但我没有这方面的基准测试)。长话短说,下面是一个工作示例:
s6fujrry2#
在为这些菜单纠结了几个月之后,我意识到我不知道它们是如何工作的,我假设update函数是用来修改现有checkbox对象的一个或多个属性的,其余的将保持不变(包括选择)。但是看起来你必须完全指定属性。因此,最近使我的程序崩溃的是忽略了包含提示文本和选项和选择。当我采用上面的通用示例并确保包含相同的提示文本并指定选择时,事情按计划进行。2谢谢你的帮助。3我从你如何修改数据列和过滤中学到了一些东西!4下面是工作代码: