Search code examples
rshinydrop-down-menudashboardrhandsontable

Create multiple rows in table based on multi-select dropdown (Shiny)


I am building a Shiny app with 2 tabs. The first tab contains 2 multi-select dropdown menus. The 2nd tab contains a table that is filtered/impacted by the selections of the 2 dropdowns from the previous tab. The first dropdown filters the table.

The second dropdown is a little different: I want the selections in the 2nd dropdown to all populate in their respective column in the table on the 2nd tab. Further, I would like an additional row to be created for each additional selection beyond the 1st selection. For example, if I had a dataset like the following:

Col1    Col2     Col3
1       a        Group1      
2       a        Group2
3       b        Group3
4       b        Group2
5       b        Group3
6       b        Group2
7       a        Group2

Let's say the first dropdown filters Col2 and I only want to see values = a. Then, we have:

Col1    Col2     Col3
1       a        Group1      
2       a        Group2
7       a        Group2

Next, I want the 2nd dropdown to able to select any of Groups 1, 2, or 3 from Col3 regardless of what is left after the first filtering step. So, if I select Group 1 and Group 3 from the dropdown on the previous tab - I want the # of rows to double. So, it would essentially look like this:

Col1    Col2     Col3
1       a        Group1     
1       a        Group3     
2       a        Group1
2       a        Group3
7       a        Group1
7       a        Group3

Here is some example code I've started on:


#----- Load libraries -----#
library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(dplyr)
library(rhandsontable)

# Define UI for application 

ui <- fluidPage(
  dashboardPage(
    dashboardHeader(title="Draft"),
    dashboardSidebar(
      sidebarMenu(
        menuItem("Filtering Questions",
                 tabName = "questions",
                 icon = icon('question')
        ),
        menuItem("All Data",
                 tabName = "all_data",
                 icon=icon("table")
        )
      )
    ),
    dashboardBody(
      tabItems(
        tabItem(
          tabName = "questions",
          selectInput(
            inputId = 'q1',
            label = '1.) Choose carb',
            choices = unique(mtcars$carb),
            selected = unique(mtcars$carb)[1],
            multiple = TRUE
          ),
          br(),
          selectInput(
            inputId = 'q2',
            label = '2.) Choose gear',
            choices = unique(mtcars$gear),
            selected = unique(mtcars$gear)[1],
            multiple = TRUE
        )),
        tabItem(
          tabName = "all_data",
          rHandsontableOutput("all_table")
        )
      ))))

# Define server logic 
server <- function(input, output) {
  
  mtcars_filter = reactive({
    filter = subset(mtcars,carb %in% input$q1)
    
    #Add in value(s) selected for gear --> will create 1, 2, or 3 possible rows per indicator
    
    return(filter)
  })
  
  #----------All Data Table----------#
  output$all_table=renderRHandsontable({
    
    
    my_table = rhandsontable(mtcars_filter()) %>%
      hot_col(c(1:11), readOnly = TRUE) %>%
      hot_context_menu(allowRowEdit = FALSE, allowColEdit = FALSE) %>%
      hot_table(highlightCol = TRUE, highlightRow = TRUE)
    
    return(my_table)
    
  })
}

# Run the application 
shinyApp(ui = ui, server = server)

How do I implement this logic to add rows based on the dropdown selections? I'm not sure how to incorporate this logic.


Solution

  • Perhaps you are looking for this

    library(shiny)
    library(shinydashboard)
    library(shinyWidgets)
    library(dplyr)
    library(rhandsontable)
    
    df <- read.table(text = 
    "col1    col2     col3
    1       a        Group1      
    2       a        Group2
    3       b        Group3
    4       b        Group2
    5       b        Group3
    6       b        Group2
    7       a        Group2", header=T)
    
    # Define UI for application 
    
    ui <- fluidPage(
      dashboardPage(
        dashboardHeader(title="Draft"),
        dashboardSidebar(
          sidebarMenu(id = "tabs",
            menuItem("Filtering Questions",
                     tabName = "questions",
                     icon = icon('question')
            ),
            menuItem("All Data",
                     tabName = "all_data",
                     icon=icon("table")
            )
          )
        ),
        dashboardBody(
          tabItems(
            tabItem(
              tabName = "questions",
              selectInput(
                inputId = 'q1',
                label = '1.) Choose col2',
                choices = unique(df$col2),
                selected = unique(df$col2)[1],
                multiple = TRUE
              ),
              br(),
              selectInput(
                inputId = 'q2',
                label = '2.) Choose col3',
                choices = unique(df$col3),
                selected = unique(df$col3)[1],
                multiple = TRUE
              )),
            tabItem(
              tabName = "all_data",
              rHandsontableOutput("all_table")
            )
          ))))
    
    # Define server logic 
    server <- function(input, output) {
    
      df_filter1 <- reactive(subset(df, col2 %in% input$q1) %>% select(-col3))
      
      my_filter <- reactive({
        df2 <- df_filter1() %>% merge(input$q2) 
        names(df2)[3] <- "col3"
        df2[order(df2$col1),]
      })
    
      #----------All Data Table----------#
      output$all_table <- renderRHandsontable({
        rhandsontable(my_filter())
      })
    }
    
    # Run the application 
    shinyApp(ui = ui, server = server)