2017-08-02 6 views
0

光沢のある階層フィルタリングに問題があります。目的は、いくつかの階層構造(例えば、地域 - 国)を有する列でdata.frameをロードし、selectInput()を使用してデータをフィルタリングすることです。また、私はドロップダウンメニューが互いに依存する必要があるので、第2のものは最初の選択にのみ関連するようにする必要があります。私のサンプルアプリはここにある:光沢のある階層データフィルタ

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を使用することができます。

問題は、不要な実行(サンプルアプリケーションにカウンタを含める)が実行されていることです。例:

  1. ユーザーがinput$class1
  2. これはclass1()反応
  3. class1()はクラス2のためupdateSelectInputobserveをトリガし、またクラス2用の更新selectInputinput$class2を変更し、class2()をトリガーdata.filter()反応
  4. をトリガをトリガを選択反応性
  5. class2()反応性トリガーdata.filter()再び

同様の事が戻っ_All_に、クラス1のためselectInputを切り替えた後に有効です。

data.filter()がリアクティブな前提条件がすべて準備完了になり、1回だけトリガーするまで「待機」する方法でこれが表示される可能性があるかどうかは疑問です。

ありがとうございます!

答えて

0

もう一つは、あなたがeventReactiveにのみ第二のクラスにバインドすることができupdateSelectInputを持っているように、とにかくトリガーので:

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

    data.all() %>% 
     filter(grepl(class1(), class1, fixed = T), 
      grepl(class2(), class2, fixed = T)) 
    }) 
関連する問題