r - Shiny 应用程序中 dbplyr 查询的条件过滤器

标签 r shiny dbplyr

我正在开发一个使用 dbplyr 查询数据库的 Shiny 应用程序,但我正在努力使用正确的语法来实现我常用的 dplyr 条件过滤器方法。看起来潜在的问题是 dbplyr 不允许您评估外部提供的向量,因此当用户提供潜在选项向量时,is.null 会失败。

<SQL>
SELECT *
FROM `mtcars`
WHERE (CASE WHEN (((4.0, 6.0) IS NULL)) THEN 1 WHEN (`cyl` IN (4.0, 6.0)) THEN 1 END)

最终,会有很多参数需要评估,所以我不想简单地将整个查询放在 if/else 语句中 as has been suggested in similar SO questions 。关于如何在基于 dbplyr 构建的 Shiny 应用程序中最好地实现条件过滤器,有什么建议吗?

# load libraries
library(dplyr)
library(dbplyr)

# create database and dataframe
mtcars_db <- tbl_memdb(mtcars)
mtcars_df <- collect(mtcars_db)

# parameterized filter function
filter_function <- function(data, user_selection) {
  {{data}} |>
    filter(
      case_when(
        is.null({{user_selection}}) ~ TRUE,
        cyl %in% {{user_selection}} ~ TRUE
      )
    )
}

# save vector of user selections
cylinders <- c(4, 6)

# works with dataframes
filter_function(mtcars_df, NULL) # works
filter_function(mtcars_df, cylinders) # works
filter_function(mtcars_db, NULL) # works
filter_function(mtcars_db, cylinders) # fails

# show query of failing version
filter_function(mtcars_db, cylinders) |>
  show_query()

最佳答案

我通常推荐@langtang 的方法,但在多种条件下,很明显这可能变得不切实际。

问题的原因是 SQL 没有办法测试整个列表(例如 (4.0, 6.0))是否为 null。因此,一个解决方案是仅测试列表的第一个值:

filter_function <- function(data, user_selection) {
  data %>%
    filter(
      cyl %in% user_selection | is.null(local(user_selection[1]))
      )
}

我使用 OR (|) 代替 case_when 并删除了 {{ }},因为它无需使用即可。但这只是一种风格选择。

该解决方案的关键部分是local,它强制在翻译之前对其内容进行评估。如果我们不包含 local ,则 dbplyr 会尝试翻译类似 (4.0, 6.0)[1] 的内容(但它无法执行此操作)。但是当我们使用 local 时,dbplyr 只需要翻译 4 (这很简单)。

这利用了 R 行为,即 NULL[1] 也是 NULL

我们必须假设 user_selection 永远不会将 NULL 作为第一个值。一般情况应该是这样。

关于r - Shiny 应用程序中 dbplyr 查询的条件过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75241005/

相关文章:

r - R中的SQLite中的表中的Collect()

R:使用 eval() 的 dbplyr

R/ggplot2 : geom_function & facet_wrap with multiple sets of parameters per facet

r - shiny.tag 上的 NSE

R plot 按频率改变线条粗细

r - ShinyManager 身份验证屏幕不会超时

r - 在 Shiny 中两次使用相同的输出元素

sql - 将正则表达式应用于 R 中的 SQL 数据库

r - 绘制动画交换(绘制方向边缘)

r - 在 R/ggplot2 中更改 True 和 False 的堆栈顺序