【问题标题】:Hierarchical data filters in shiny闪亮的分层数据过滤器
【发布时间】:2017-08-02 13:32:11
【问题描述】:

我对闪亮的分层过滤有疑问。目标是加载具有某些层次结构(例如区域 - 国家)的列的 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)

注意:如果选择了 _All_ 选项,class1()class2 反应式将返回一个空字符串。那么就可以使用dplyr::filter了。

问题是我遇到了不必要的执行(我在示例应用程序中包含了一个计数器)。示例:

  1. 用户选择input$class1
  2. 这会触发 class1() 反应式
  3. class1() 触发 observeupdateSelectInput 用于第 2 类,还触发 data.filter() 反应
  4. 2 类的更新 selectInput 更改 input$class2 并触发 class2() 反应
  5. class2() 响应式再次触发 data.filter()

将 1 类的 selectInput 切换回 _All_ 后,类似的事情也有效。

问题是您是否可以看到这可能以data.filter() 反应式将“等待”直到所有反应式先决条件都准备好并且仅触发一次的方式编写。

提前致谢!

【问题讨论】:

    标签: r shiny


    【解决方案1】:

    既然第二个触发了,因为你有updateSelectInput,你只能用eventReactive将它绑定到第二个类:

     data.filter <- eventReactive(class2(),{
        isolate(counter(counter() + 1))
    
        data.all() %>%
          filter(grepl(class1(), class1, fixed = T),
                 grepl(class2(), class2, fixed = T))
      })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-04
      • 2018-10-04
      • 1970-01-01
      • 2018-12-02
      • 2017-05-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多