4

我正试图将我的头脑围绕准报价,以便我可以将它与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.

4

2 回答 2

5

您想将列名捕获为符号

col <- ensym(col)

而不是quo()然后使用

expr(dt[, !!col])

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

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

但实际上,quasinotation 的东西在 tidyverse 中效果最好,而不是原生的 data.table 函数。“data.table”方式可能更像是这个现有问题中的内容:Pass column name in data.table using variable。data.table 非常喜欢字符串而不是符号。

于 2019-10-21T15:27:53.350 回答
1

您可以使用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 中选择它。在第二种情况下,我们在 data.table 的上下文中评估(使用eval)参数的名称

于 2019-10-21T15:29:27.247 回答