data.table 的准引用

Quasiquotation with data.table

我正在努力思考准引用,以便我可以将它与 data.table 调用一起使用。这是一个例子:

library(data.table)
library(rlang)
dt <- data.table(col1 = 1:10, col2 = 11:20)

dt[, col1]

如果我想把它包装成函数,我该怎么做?我试过了:

foo <- function(dt, col) {
  col <- quo(col)

  expr(dt[, !!col1])
}

foo(dt, col1)

但得到Error in enexpr(expr) : object 'col1' not found。我假设我遗漏了一些步骤,因为 data.table 对此的评估不同于 dplyr

您想将列名称捕获为带有

的符号
col <- ensym(col)

而不是 quo() 然后使用

expr(dt[, !!col])

(不是那里不存在的 col1),但这只是 return 一个表达式。如果你想评估它,你需要

eval_tidy(expr(dt[, !!col]))

但实际上准符号在 tidyverse 中效果最好,而不是 data.table 原生函数。 "data.table" 方式可能更像是这个现有问题中的方式:Pass column name in data.table using variable。 data.table 比起符号更喜欢字符串。

您可以使用 deparsesubstitute 并使用参数 with=FALSE,如 :

foo <- function(dt, col){
  col_str = deparse(substitute(col))
  dt[, col_str, with = F]
}

或者您可以使用 evalsubstitute 并使用默认的 data.table 参数 with=TRUE,如 :

foo <- function(dt, col){
  col_symb = substitute(col)
  dt[, eval(col_symb)] # by default: with=TRUE
}

在这两种情况下,substitute 将获得您传递给参数 col 的参数的 名称。在第一种情况下,deparse 会将此名称转换为字符串,从而使我们能够使用 with = FALSE 从 data.table 中 select 它。在第二种情况下,我们在 data.table.

的上下文中评估(使用 eval)参数的 name