如何允许用户按多个条件过滤数据框?

How to allow the user to filter data frame by multiple criteria?

我正在使用一个大型数据库,我希望用户能够使用多个条件或过滤器从数据库中提取行。

假设一个数据框如下所示,其中包含 3 种水果并列出了它们的原产地和手头数量。发布的 MWE 代码允许用户 select 要查看的水果类型,可以是单个水果,也可以是多个水果 selection。这工作正常,在最底部的图像中,我显示了用户select吃香蕉和蓝莓的结果。

      Fruit Origin Qty
1    Banana     MX   5
2 Blueberry     OR  15
3    Cherry     PA  50

我需要帮助扩展此 MWE 以允许:

  1. 另外 select 通过第二个 select 框按“来源”获取水果 当前“水果”select 框的右侧。它们不一定需要链接,但如果它没有使事情过于复杂就更好了。 (所谓“未链接”,我的意思是如果用户决定 select 按 Origin,任何 Fruit select 离子都会被忽略和覆盖)。
  2. 在当前使用的 multiInput() 函数中,或任何其他包或 有人推荐的功能,如何自动 输入可用的唯一行 ID 选择,而不是手动键入 他们在编写代码时,例如 choices = c("Banana", "Blueberry", "Cherry") 下面一行?在我使用的实际数据库中,也有 许多行 ID 需要手动输入。
  3. 对于用户的选择,对于“水果”和“产地”,如何合并一个选项“全部”?

也许我需要另一个包裹。

MWE 代码:

library("shiny")
library("shinyWidgets")

ui <- fluidPage(
  multiInput(
    inputId = "id", 
    label = "Fruits :",
    choices = c("Banana", "Blueberry", "Cherry"),
    selected = "Banana", width = "400px",
    options = list(enable_search = FALSE,
                   non_selected_header = "Choose between:",
                   selected_header = "You have selected:"
                  )
  ),
  tableOutput("table")
)

server <- function(input, output, session) {
  
  data <- data.frame(Fruit=c("Banana", "Blueberry", "Cherry"), 
                     Origin=c("MX","OR","PA"), 
                     Qty=c(5,15,50)
                    )
  
  observeEvent(input$id,{
    dataSelect <- data[data$Fruit %in% c(input$id), ]
    output$table <-  renderTable(dataSelect)
    })
  
}

shinyApp(ui = ui, server = server)

  • 您可以使用 updateMultiInput 根据 table 中的值更新选择,而不是在 UI
  • 中对它们进行硬编码
  • 您可以创建一个复选框来显示所有内容
  • 目前,行必须同时包含选定的水果和原产地。如果其中任何一个都可以,请将 (Fruit %in% input$fruit & Origin %in% input$origin) 替换为 (Fruit %in% input$fruit | Origin %in% input$origin)
library("dplyr")
library("shiny")
library("shinyWidgets")

ui <- fluidPage(
  multiInput(
    inputId = "fruit",
    label = "Fruits :",
    choices = c(""),
    selected = "",
    width = "400px",
    options = list(
      enable_search = FALSE,
      non_selected_header = "Choose between:",
      selected_header = "You have selected:"
    )
  ),
  multiInput(
    inputId = "origin",
    label = "Origins :",
    choices = c(""),
    selected = "",
    width = "400px",
    options = list(
      enable_search = FALSE,
      non_selected_header = "Choose between:",
      selected_header = "You have selected:"
    )
  ),
  checkboxInput(inputId = "all", label = "show all"),
  tableOutput("table")
)

server <- function(input, output, session) {
  data <- data.frame(
    Fruit = c("Banana", "Blueberry", "Cherry"),
    Origin = c("MX", "OR", "PA"),
    Qty = c(5, 15, 50)
  )

  updateMultiInput(session, "fruit", choices = unique(data$Fruit),
    selected = unique(data$Fruit)[[1]])
  updateMultiInput(session, "origin", choices = unique(data$Origin),
    selected = unique(data$Origin)[[1]])

  observeEvent(
    eventExpr = {
      input$fruit
      input$origin
    },
    handlerExpr = {
      output$table <- renderTable({
        filter(data,
          (Fruit %in% input$fruit & Origin %in% input$origin) |
           input$all
        )
      })
    }
  )
}

shinyApp(ui = ui, server = server)