我遇到了闪亮的分层过滤问题。目标是使用具有某种层次结构的列(例如区域 - 国家/地区)加载data.frame,并使用selectInput()
来过滤数据。此外,我需要下拉菜单相互依赖,以便第二个菜单仅与第一个选择相关。我的示例应用程序在这里:
library(shiny)
library(dplyr)
data <- data.frame(
class1 = rep(c("a", "b", "c"), each = 4),
class2 = c(rep(c("a1", "a2"), each = 2), rep(c("b1", "b2"), each = 2),
rep(c("c1", "c2"), each = 2)),
val = 1:12,
stringsAsFactors = F
)
ui <- fluidPage(sidebarLayout(
sidebarPanel(
actionButton('loaddata', 'Load Data'),
br(), br(),
selectInput('class1', 'Class 1',
choices = c('Select class 1' = '')),
selectInput('class2', 'Class 2',
choices = c('Select class 1 first' = ''))
),
mainPanel(
verbatimTextOutput("out"),
verbatimTextOutput("counter")
)
))
server <- function(input, output, session) {
counter <- reactiveVal(0)
data.all <- eventReactive(input$loaddata, {
data
})
class1 <- reactive({
if (input$class1 == '_All_') return('')
else return(input$class1)
})
class2 <- reactive({
if (input$class2 == '_All_') return('')
else return(input$class2)
})
observe({
class1 <- c('_All_', data.all()$class1)
updateSelectInput(session, 'class1', choices = class1)
})
observe({
if (class1() == '') {
class2 <- c('Select class 1 first' = "")
} else {
class2 <- data.all() %>%
filter(grepl(class1(), class1, fixed = T)) %>%
.$class2 %>% c('_All_', .)
}
updateSelectInput(session, 'class2', choices = class2)
})
data.filter <- reactive({
isolate(counter(counter() + 1))
data.all() %>%
filter(grepl(class1(), class1, fixed = T),
grepl(class2(), class2, fixed = T))
})
output$out <- renderPrint({ data.filter() })
output$counter <- renderPrint({ counter() })
}
shinyApp(ui, server)
注意:如果选择了class1()
选项,class2
和_All_
被动反应将返回空字符串。然后可以使用dplyr::filter
。
问题是我遇到了不必要的执行(我在示例应用程序中包含了一个计数器)。例如:
input$class1
class1()
被动class1()
针对第2课触发observe
updateSelectInput
,并触发data.filter()
被动selectInput
更改input$class2
并触发class2()
被动class2()
被动触发器data.filter()
再次将第1课的selectInput
切换回_All_
后,类似的内容有效。
问题是,如果你能看到任何方式,data.filter()
被动将“等待”,直到所有被动先决条件都准备好并且只触发一次。
提前致谢!
答案 0 :(得分:0)
由于第二个触发因为你有updateSelectInput
,你只能用eventReactive
将它绑定到第二个类:
data.filter <- eventReactive(class2(),{
isolate(counter(counter() + 1))
data.all() %>%
filter(grepl(class1(), class1, fixed = T),
grepl(class2(), class2, fixed = T))
})