Putting a filter based on a previous filter in Shiny

Hi. I am a beginner to R shiny. As practice, I am working on gapminder dataset. I have 2 filters. The first is of continent and second of countries. Once I select a continent, only the relevant countries must appear in the next filter. How can I do this?

library(tidyverse)
library(shiny)
library(shinydashboard)
#> 
#> Attaching package: 'shinydashboard'
#> The following object is masked from 'package:graphics':
#> 
#>     box
library(janitor)
#> 
#> Attaching package: 'janitor'
#> The following objects are masked from 'package:stats':
#> 
#>     chisq.test, fisher.test
library(gapminder)
library(ggthemes)
gapminder<-gapminder %>% clean_names()

ui<-dashboardPage(
  skin="red",
  dashboardHeader(title="Life expectancy across continents",titleWidth = 500),
  dashboardSidebar(selectInput("continent","Select the continent",choices = sort(unique(gapminder$continent)),multiple=T,selected="Asia"),
                   selectInput("country","Select the country",choices=unique(gapminder$country),multiple=T)),
  dashboardBody(
    tabsetPanel(
      type="tabs",
      id="tab_selected",
      tabPanel(title="Continent-view",
               plotOutput("plot1"))
    )
  )
)


server<-function(input,output){
  continent<-reactive({
    gapminder %>% 
      filter(continent %in% input$continent) %>% 
      group_by(continent,year) %>% 
      summarise(mean_exp=mean(life_exp),.groups = "drop") 
  })
  
  output$plot1<-renderPlot({
    ggplot(continent(),aes(year,mean_exp,color=continent))+
      geom_line(size=1.5)+
      theme_minimal()+
      labs(title="How has life expectancy increased across different continents in the post-war period?",x="Year",y="Average Life Expectancy")
  })
}

shinyApp(ui,server)
#> PhantomJS not found. You can install it with webshot::install_phantomjs(). If it is installed, please make sure the phantomjs executable can be found via the PATH variable.
Shiny applications not supported in static R Markdown documents
Created on 2022-03-07 by the reprex package (v2.0.1)

Hi there,

You can use the updateSelectInput function to change the choices of an input dynamically through the server. Here is an example

library(tidyverse)
library(shiny)
library(shinydashboard)
library(janitor)
library(gapminder)
library(ggthemes)

gapminder<-gapminder %>% clean_names()
#Get all the unique continents and their countries
countryNames = gapminder %>% select(continent, country) %>% 
  distinct() %>% arrange(country)

ui<-dashboardPage(
  skin="red",
  dashboardHeader(title="Life expectancy across continents",titleWidth = 500),
  dashboardSidebar(selectInput("continent","Select the continent",choices = sort(unique(gapminder$continent)),multiple=T,selected="Asia"),
                   selectInput("country","Select the country",choices=c(),multiple=T)),
  dashboardBody(
    tabsetPanel(
      type="tabs",
      id="tab_selected",
      tabPanel(title="Continent-view",
               plotOutput("plot1")),
      tabPanel(title="Country-view",
               plotOutput("plot2"))
    )
  )
)


server<-function(input, output, session){
  
  #Data per continent
  continent<-reactive({
    gapminder %>% 
      filter(continent %in% input$continent) %>% 
      group_by(continent,year) %>% 
      summarise(mean_exp=mean(life_exp),.groups = "drop") 
  })
  
  #Data per country
  countries<-reactive({
    gapminder %>% 
      filter(country %in% input$country) %>% 
      group_by(country,year) %>% 
      summarise(mean_exp=mean(life_exp),.groups = "drop") 
  })
  
  #Change country input optoins if continents change
  observeEvent(input$continent, {
    
    #Filter countries based on current continent selection
    countriesToShow = countryNames %>% 
      filter(continent %in% input$continent) %>% pull(country)
    
    #Update the actual input
    updateSelectInput(session, "country", choices = countriesToShow, 
                      selected = countriesToShow[1])
    
  })
  
  #Plot the continent data
  output$plot1<-renderPlot({
    ggplot(continent(),aes(year,mean_exp,color=continent))+
      geom_line(size=1.5)+
      theme_minimal()+
      labs(title="How has life expectancy increased across different continents in the post-war period?",x="Year",y="Average Life Expectancy")
  })
  
  #Plot the country data
  output$plot2<-renderPlot({
    ggplot(countries(),aes(year,mean_exp,color=country))+
      geom_line(size=1.5)+
      theme_minimal()+
      labs(title="How has life expectancy increased across different countries in the post-war period?",x="Year",y="Average Life Expectancy")
  })
}

shinyApp(ui,server)

I also added a new tab with plot per country so you can see how it would work if you select different countries.

Hope this helps,
PJ

Thanks a lot for this. My next objective was to do country-wise tab.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.