Search code examples
rshinydt

Reactive data table in Shiny with optional filtering


I have a double problem creating a simple Shiny app. I know this topic was covered in several other questions, but having studied them, I havent found a question that would fully cover my problems.

I want to render mtcars table (full 32 rows as a default option) and then I want to apply a reactive filter on the number of gears with multiple selection allowed.

The following code doesnt work in a number of ways:

  1. The mtcars table is not rendered unless filter on gears is set. Instead -I got an error message in the app: "Result must have length 32, not 0"

  2. Choosing multiple gears levels does not add up correctly. When I select each gear number separately, the table is rendered correctly, but, lets say, when I combine to show gear number 3 and 4, I got only 10 rows return, which is incorrect.

 ui <- fluidPage(
  sidebarLayout(
    mainPanel(
   
      selectInput("pickvalue", label = "Gears", mtcars$gear,
                  selected = NULL, multiple = T)),
     
    
      tableOutput("tableOut")
      
    )
  )


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

  
 gears <- reactive({
    mtcars %>%  filter(gear == input$pickvalue) %>% select(-gear)
  })
  
  output$tableOut<- renderTable({gears()
  })
  
}

shinyApp(ui = ui, server=server)

Solution

  • The key to your problems are

    1. Create an if statement when your input is NULL (i.e. when you first open the app) that will just spit out the dataset
    2. When selecting multiple inputs, you need to use %in% operator

    See code below:

    ui <- fluidPage(
      sidebarLayout(
        mainPanel(
    
          selectInput("pickvalue", label = "Gears", unique(mtcars$gear),
                      selected = NULL, multiple = T)),
    
    
        tableOutput("tableOut")
    
      )
    )
    
    
    server <- function(input, output, session){
    
    
      gears <- reactive({
    
        dat <- mtcars
    
        if (!is.null(input$pickvalue)){dat <- dat %>% filter(gear %in% input$pickvalue)} 
    
        dat <- dat %>% select(-gear)
    
        return(dat)
    
      })
    
      output$tableOut<- renderTable({gears()})
    
    }
    
    shinyApp(ui = ui, server=server)