DT数据表调用过滤条件

Calling filtering conditions in DT datatables

我正在构建一个使用 DT::renderDataTable() 的闪亮应用。它提供了一个用于可视化和过滤数据集的优雅面板。

我知道 DT::renderDataTable 会自动将过滤后的数据集传递给进一步的操作。但出于某种原因,现在我还需要 动态调用那些过滤条件 。 “调用过滤条件”是指提取此条件的确切表达式。例如,如果我将变量 x 的过滤更改为在范围 (-1, 1) 内,我想输出一个 (x > -1) & (x < 1) 或类似的表达式。

有人知道如何实现吗?提前致谢!

您可以使用 input$<tableId>_search_columns 访问搜索字符串。 他们使用自定义格式(例如,范围 (-1, 1) 将是 "-1 ... 1"), 并且 DT 中没有公开 API 用于从搜索中解析 R 表达式 字符串,所以你需要自己写一个解析器。

这是一个可以帮助您入门的函数:

parse_search_expressions <- function(data, search) {
  parse_search_expression <- function(x, s) {
    if (!nzchar(s)) return(TRUE)
    if (is.numeric(x)) {
      r <- strsplit(s, "...", fixed = TRUE)
      r <- sapply(r, as.numeric)
      bquote((x >= .(r[1])) & (x <= .(r[2])))
    } else if (is.factor(x) || is.logical(x)) {
      v <- jsonlite::fromJSON(s)
      bquote(x %in% .(v))
    } else {
      bquote(grepl(.(s), x, fixed = TRUE))
    }
  }
  Map(parse_search_expression, data, search)
}

tbl <- data.frame(x = 1:3, y = factor(LETTERS[1:3]), z = c("foo", "bar", "baz"))
str(parse_search_expressions(tbl, c("1 ... 2", "[\"A\"]", "ba")))
#> List of 3
#>  $ x: language (x >= 1) & (x <= 2)
#>  $ y: language x %in% "A"
#>  $ z: language grepl("ba", x, fixed = TRUE)

如果你只是想应用过滤器,有doColumnSearch()(添加在 DT 0.22) 这将使您获得与搜索字符串匹配的索引:

str(Map(DT::doColumnSearch, tbl, c("1 ... 2", "[\"A\"]", "ba")))
#> List of 3
#>  $ x: int [1:2] 1 2
#>  $ y: int 1
#>  $ z: int [1:2] 2 3

如果足够的话,我会推荐后者,因为你保证 得到与 DT 过滤相同的结果。用第一种方法你有 复制过滤逻辑,由您来确保结果 是一样的。

最后,以下是如何在应用中使用这两种方法:

library(shiny)
library(DT)

ui <- fluidPage(
  DTOutput("table"),
  verbatimTextOutput("expression"),
  verbatimTextOutput("search_result")
)

server <- function(input, output, session) {
  output$table <- renderDT(iris, filter = "top")
  output$expression <- renderPrint({
    str(parse_search_expressions(iris, input$table_search_columns))
  })
  output$search_result <- renderPrint({
    str(Map(doColumnSearch, iris, input$table_search_columns))
  })
}

shinyApp(ui, server)