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)
我正在构建一个使用 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)