observe updateSelectInput based on first selection

2019-02-24 23:51发布

问题:

My server.R has the following code, I would like my Shiny app to chose States based on the Country Selection, but it shows all states in the second line. I guess here, observe is only observing not performing any action.

  shinyServer(function(input, output, session) {

      observe({
          ddf = df[df$Date>=input$daterange[1] & df$Date<=input$daterange[2],]
          updateSelectInput(session, "Country", choices = ddf$Country)
          ddf1 = subset(ddf, grepl(input$Country, ddf$State))
          updateSelectInput(session, "State", choices =  ddf1$State)  
            })

    }

Based on above selection, I want to pass some data frame for plotting. When I select different country it is changing states list for a second and going back to all First country's state list. I really appreciate if some one can show an example here. My ui.R code is below

 sidebarPanel(
    wellPanel(dateRangeInput("daterange", "Date range:",
                      Sys.Date()-10,
                      Sys.Date()+10)),
    wellPanel(selectInput("Country", "Select a Country:",
                          '')),
    wellPanel(selectInput("State", "Select a State:",
                          '')))

回答1:

I think there's like a conflict in your observer cause it contains input$Country as well as an updater for the Country input. Then I'd try to split it into two observers, and I'd use a reactive conductor to make ddf only once.

get_ddf <- reactive({
  df[df$Date>=input$daterange[1] & df$Date<=input$daterange[2],]
})
observe({
  updateSelectInput(session, "Country", choices = get_ddf()$Country)
})
observe({
  ddf1 = subset(get_ddf(), grepl(input$Country, get_ddf()$State))
  updateSelectInput(session, "State", choices =  ddf1$State)  
})

Moreover, shouldn't you use the levels of the column rather than the column itself in the choices argument ?

observe({
  updateSelectInput(session, "Country", choices = levels(droplevels(get_ddf()$Country)))
})
observe({
  ddf1 = droplevels(subset(get_ddf(), grepl(input$Country, get_ddf()$State)))
  updateSelectInput(session, "State", choices =  levels(ddf1$State))  
})

If the Country and State columns are not factors but characters, use unique() instead of levels(droplevels()).