lumiukko
lumiukko

Reputation: 259

R Shiny - filter data.frame with checkboxGroupInput

Trying to filter the data in a data frame depending on what check boxes are checked. Take the following example:

if (interactive()) {
  library(DT)

  Dish <- c("Apple Pie", "Apple Cake", "Blueberry Pie", "Lemon", "Carrot", "Chocolate")
  DishNum <- c("123", "456", "789", "12", "34", "56")
  data <- data.frame(Dish, DishNum)

  ui <- fluidPage(
    checkboxGroupInput(inputId = "chkDish",
                       label = "",
                       inline = TRUE,
                       choices = c("Apple", "Blue", "Not Apple or Blue"),
                       selected = c("Apple", "Blue", "Not Apple or Blue")
    ),
    DT::dataTableOutput(outputId = "DT_Dish")
  )

  server <- function(input, output, session) {
    output$DT_Dish <- DT::renderDataTable({
      DT::datatable(
        data,
        rownames = FALSE,
        options = list(
          dom = 't',
          searchHighlight = TRUE,
          pageLength = 100,
          scrollX = TRUE
        )
      )
    })
  }
  shinyApp(ui, server)
}

If only the "Apple" box is checked, it would only show the data in the table beginning with "Apple". If only the "Blue" box is checked, it would only show the data in the table beginning with "Blue". If only the "Not Apple or Blue" box is checked, it would only show the data in the table NOT beginning with "Apple" or "Blue".

If any combination of the buttons are checked, it would filter/show the data appropriately.

I understand I'd need to use some wildcard for subsetting the data, but not sure the best way to approach this. Thanks!

Upvotes: 2

Views: 659

Answers (1)

Ben
Ben

Reputation: 30474

One way to approach this is to set up regex filters based on your check boxes. An if_else statement is included to check for the not apple or blue specific case. Otherwise will use the input$chkDisk character values in the regex. All of the filters are searched with an or (|). See if this provides the desired behavior.

library(dplyr)

server <- function(input, output, session) {       
  filtered_data <- reactive({
    req(input$chkDish)
    filters <- if_else(input$chkDish == "Not Apple or Blue", "(?!Apple)(?!Blue)", paste0("(", input$chkDish, ")"))
    filter(data, grepl(paste0("^(", paste0(filters, collapse="|"), ")"), Dish, perl = TRUE))
  })

  output$DT_Dish <- DT::renderDataTable({
    DT::datatable(
      filtered_data(),
      rownames = FALSE,
      options = list(
        dom = 't',
        searchHighlight = TRUE,
        pageLength = 100,
        scrollX = TRUE
      )
    )
  })
}

Upvotes: 1

Related Questions