Search code examples
rdplyrfiltershinydataset

Filter values based on column values (in a Shiny reactive)


I'm working on a survey dataset. I have answers (column 2) by people from different countries (column 1).

Column 1 Column 2
China Answer A
China Answer B
France Answer A
France Answer C
Italy Answer B

My Shiny app (https://aurelienmaignant.shinyapps.io/shiny/) displays plots and allow the user to filter by country (with reactive plots). I'm using dlpyr,

I want to create a plot that shows only the values in col2 that are shared at least once by all selected countries (col1).

For example, if the user in shiny selects "China" and "France", the plot output should display only "Answer A" (because answer A is answered at least once by someone from France and at least once by someone from China).

If the user in shiny selects "China", "France" and "Italy", the output should be "None", because none of the three answer (A, B or C) is shared at least once by someone from each countries.

Thanks for your help


Solution

  • Welcome to SO community, next time please post a minimal reproducible example so others would be able to better help you!

    I've made a mini app which does the job for you:

    ### Loading the libraries
    
    library(tidyverse)
    library(shiny)
    
    ### Building your sample data frame
    
    df <- data.frame("col1" = c("china", "china", "france", "france", "italy"),
                     "col2" = c("A", "B", "A", "C", "B"))
    
    ### The user interface part
    
    ui <- fluidPage(fluidRow(
      column(4,
             ### The widget to get the input from user
             selectInput("select", label = "Select box", 
                         choices = unique(df$col1),
                         multiple = TRUE)),
      column(4,
             ### The output to show the mutual options
             textOutput("result")
      ))
    )
    
    ### The server part
    
    server <- function(input, output) {
    
      output$result <- renderText({
        tmp <- df %>% filter(col1 %in% input$select)
        tmp <- tmp[with(tmp, col2 == Reduce(intersect, split(col2, col1))),]
        unique(tmp$col2)
      })
      
    }
    
    ### Running the app
    
    shinyApp(ui = ui, server = server)
    

    In the server, I filter the dataset for the countries that the user selected, and using intersect() we can find the mutual values in the 2nd column based on the first column. For more details on that line you can take a look at this SO post here to see how it's done.