2

我一直在尝试创建一个在 Shiny 应用程序中使用的通用函数,该函数将允许使用侧边栏菜单按任意条件列表过滤数据框。因此,您可以使用侧边栏菜单来选择要过滤的列和要过滤的条件。

这是我使用 mtcars 数据集创建的当前适用于我的目的的 Rmd 的精简可重现示例:

https://github.com/keithmcnulty/flexfiltering/blob/master/index.Rmd

请参阅我的函数filter1_by,filter2_by等,dplyr::filter_at因为我必须将列名与非标准评估中的值区别对待。这迫使我必须根据我想要的过滤器数量来创建几个函数。例如:

filter2_by <- function(df, f1, fv1, f2, fv2) {
  filter_f1 <- quo(f1)
  filter_f2 <- quo(f2)

df %>%
  dplyr::filter_at(vars(!!filter_f1), all_vars(. == fv1)) %>%
  dplyr::filter_at(vars(!!filter_f2), all_vars(. == fv2))
}

我真正想做的只是创建一个函数filter_by(df, ...),它将接受任意一组过滤条件,例如:

filter_by(mtcars, input$filter1 == input$filter1val, 
                  input$filter2 == input$filter2val)

希望有任何关于如何编码的建议filter_by

谢谢!

4

1 回答 1

3

dplyr不是实现目标的唯一选择。通过简单的 Google 搜索,可以找到许多不同的方法来过滤 R 中的数据框。实际上,这里解决问题的关键是了解 Shiny 框架(即返回类型、反应性等),因为您需要根据上下文中的需要调整任何过滤方法。

下面是一个简洁的 Shiny 示例,其中包含您想要的所有内容。除了您所说的过滤问题外,您的代码非常复杂。updateSelectInput会是你的朋友。

library(shiny)
library(kableExtra)

ui <- fluidPage(
  selectInput(
    inputId = "column",
    label = "Choose a column",
    choices = names(mtcars),
    selected = "mpg"
  ),
  selectInput(
    inputId = "value",
    label = "Filter by:",
    choices = sort(mtcars$mpg),
    multiple = T
  ),
  htmlOutput(
    outputId = "table"
  )
)

server <- function(input, output, session) {
  observeEvent(input$column, {
    updateSelectInput(
      session = session,
      inputId = "value",
      choices = sort(mtcars[[input$column]]),
      selected = sort(mtcars[[input$column]])[1]
    )
  })
  output$table <- renderText({
    if(length(input$value) != 0) {
      kable(
        mtcars[mtcars[[input$column]] %in% as.numeric(input$value), ]
        ## just chain any additional conditions using &:
        # mtcars[
        #   mtcars[[input$column]] %in% as.numeric(input$value) &
        #   mtcars[[input$column2]] %in% as.numeric(input$value2) &
        #   mtcars[[input$column3]] %in% as.numeric(input$value3)
        # , ]
      )
    }
  })
}

shinyApp(ui = ui, server = server)
于 2018-07-30T07:30:31.797 回答