2017-08-02 72 views
0

我有閃亮的分層過濾問題。我們的目標是加載一個data.frame,其中包含一些分層結構的列(例如region-country),並使用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 reactives是如果選擇_All_選項有返回一個空字符串。然後可以使用dplyr::filter

問題是我遇到了不必要的執行(我在示例應用程序中包含了一個計數器)。例如:

  1. 用戶選擇input$class1
  2. 這觸發class1()反應
  3. class1()觸發observeupdateSelectInput 2類和還觸發data.filter()反應
  4. 2類更新selectInput改變input$class2並觸發class2()反應性
  5. class2()反應性觸發器data.filter()再次

類似的事情是切換selectInput 1級回_All_後有效。

問題是,如果你能看到這種方式,data.filter()被動方式將會「等待」,直到所有被動的先決條件準備就緒並且只觸發一次。

在此先感謝!

回答

0

由於第二個觸發反正你有updateSelectInput可將其綁定只對第二類eventReactive

data.filter <- eventReactive(class2(),{ 
    isolate(counter(counter() + 1)) 

    data.all() %>% 
     filter(grepl(class1(), class1, fixed = T), 
      grepl(class2(), class2, fixed = T)) 
    })