简体   繁体   中英

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!

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
      )
    )
  })
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM