Nihat
Nihat

Reputation: 59

SelectizeInput filtering in R Shiny

I have 2 questions: 1) I would like to know if that is possible to make a column of selections depending on the previous input. Please see the code and I will explain what I mean:

library(shiny)

Country <- c("USA", "Mexico", "Canada", "China", "Vietnam", "India", "France", "Germany", "Poland")
Region <- c("Americas", "Americas", "Americas", "Asia", "Asia", "Asia", "Europe", "Europe", "Europe")
Product <- c(11, 22, 33, 44, 55, 66, 77, 88, 99)
Date <- c(1, 2, 3, 4, 5, 6, 7, 8, 9)
DF <- cbind(Region, Country, Product, Date)
DF <- as.data.frame(DF)

Region <- as.factor(sort(unique(DF$Region)))
Country <- as.factor(sort(unique(DF$Country)))

ui <- fluidPage(titlePanel("Filtering experiments"),
sidebarLayout(
    # Sidebar panel for inputs ----
    sidebarPanel(width = 3,

           selectizeInput("RegionSelect", "Region", Region, selected = NULL, multiple = TRUE),
           selectizeInput("CountrySelect", "Country", Country, selected = NULL, multiple = TRUE)),

    # Main panel for displaying outputs ----
    mainPanel( fluidPage(  box(width = 12, tableOutput("table")) )     )    )   )server <- function(input, output) {

output$table <- renderTable({
    filtered <- DF
    if (!is.null(input$RegionSelect)) {filtered <- filtered %>% filter(Region == input$RegionSelect)}
    if (!is.null(input$CountrySelect)) {filtered <- filtered %>% filter(Country == input$CountrySelect)}

    Total <- data.frame(filtered$Product)
    ShowTable <- data.frame(cbind(Total))
    ShowTable
})}shinyApp(ui, server)

Whenever the Region is selected as "Americas" the user still see all of the countries, not only US, Canada and Mexico.

I tried to fix it by filtering like:

       selectizeInput("CountrySelect", "Country", as.factor(sort(unique(filtered$Country %>% filter(Region == input$RegionSelect)}))), selected = NULL, multiple = TRUE))

But it did not work, so I hope you have some ideas.

2) Even if the " multiple = TRUE", whenever there are 2 or more inputs chosen in the same Input line the application stops working.

Thanks in advance!

Upvotes: 1

Views: 728

Answers (2)

bretauv
bretauv

Reputation: 8506

You can use updateSelectizeInput to update the content of selectizeInput according to the value of another input.

Note that it is better to use observeEvent than observe statements (see here for details).

library(shiny)
library(dplyr)

Country <- c("USA", "Mexico", "Canada", "China", "Vietnam", "India", "France", "Germany", "Poland")
Region <- c("Americas", "Americas", "Americas", "Asia", "Asia", "Asia", "Europe", "Europe", "Europe")
Product <- c(11, 22, 33, 44, 55, 66, 77, 88, 99)
Date <- c(1, 2, 3, 4, 5, 6, 7, 8, 9)
DF <- cbind(Region, Country, Product, Date)
DF <- as.data.frame(DF)

Region <- as.factor(sort(unique(DF$Region)))
Country <- as.factor(sort(unique(DF$Country)))

ui <- fluidPage(titlePanel("Filtering experiments"),
                sidebarLayout(
                  # Sidebar panel for inputs ----
                  sidebarPanel(
                    width = 3,

                    selectizeInput(
                      "RegionSelect",
                      "Region",
                      Region,
                      selected = NULL,
                      multiple = TRUE
                    ),
                    selectizeInput(
                      "CountrySelect",
                      "Country",
                      Country,
                      selected = NULL,
                      multiple = TRUE
                    )
                  ),

                  # Main panel for displaying outputs ----
                  mainPanel(fluidPage(
                    width = 12, tableOutput("table")
                  ))
                ))

server <- function(input, output, session) {

  observeEvent(input$RegionSelect, {
    req(input$RegionSelect)
    test <- DF %>%
      filter(Region %in% input$RegionSelect) %>%
      select(Country)

    updateSelectizeInput(session, 
                         inputId = "CountrySelect",
                         choices = test)
  })

  output$table <- renderTable({
    # Uncomment the two lines with comments if you want to make it mandatory to chose a continent to show the table

    # req(input$RegionSelect)
    req(input$CountrySelect)
    DF %>%
      # filter(Region %in% input$RegionSelect) %>%
      filter(Country %in% input$CountrySelect)
  })}
shinyApp(ui, server)

Upvotes: 1

Remko Duursma
Remko Duursma

Reputation: 2821

You can add an updateSelectInput, like this:

     observe({

         region <- input$RegionSelect
         req(region)

         updateSelectInput(session, "CountrySelect", 
              choices = filter(DF, Region == !!region)$Country)

                    })

Also, please fix your (nearly) working example: you need a library(dplyr), and remove box (since that is from shinydashboard only, which you are not using).

Upvotes: 1

Related Questions