R: dbplyr 使用 eval()

问题描述

我有一个关于如何在 eval(parse(text=...)) sql 翻译中使用 dbplyr 的问题。 以下代码使用 dplyr

完全符合我对 eval(parse(text=eval_text)) 的要求
selected_col <- c("wt","drat")

text <- paste(selected_col,">3")

implode <- function(...,sep='|') {
  paste(...,collapse=sep)
}

eval_text <- implode(text)

mtcars %>% dplyr::filter(eval(parse(text=eval_text)))

但是当我将它放入数据库时​​,它返回一条错误消息。我正在寻找任何允许我使用 or 运算符动态设置列名和过滤器的解决方案。

db <- tbl(con,"mtcars") %>%
     dplyr::filter(eval(parse(eval_text)))

db <- collect(db)

谢谢!

解决方法

正确的方法,但 dbplyr 倾向于使用可以接收 !! 运算符('bang-bang' 运算符)的东西更好地工作。在某一时刻 dplyr 有 *_ 版本的函数(例如 filter_)接受文本输入。这现在是使用 NSE(非标准评估)完成的。

几个参考:shiptechr-bloggers(抱歉找不到官方的 dplyr 参考)。

为了您的目的,您应该找到以下作品:

library(rlang)
df %>% dplyr::filter(!!parse_expr(eval_text))

全面工作:

library(dplyr)
library(dbplyr)
library(rlang)
data(mtcars)
df = tbl_lazy(mtcars,con = simulate_mssql()) # simulated database connection

implode <- function(...,sep='|') { paste(...,collapse=sep) }

selected_col <- c("wt","drat")
text <- paste(selected_col,">3")
eval_text <- implode(text)

df %>% dplyr::filter(eval(parse(eval_text))) # returns clearly wrong SQL

df %>% dplyr::filter(!!parse_expr(eval_text)) # returns valid & correct SQL

df %>% dplyr::filter(!!!parse_exprs(text)) # passes filters as a list --> AND (instead of OR)