如何在函数内部使用data.table?

时间:2014-05-28 11:10:56

标签: r data.table

作为一个最小的工作示例,例如,我希望能够动态地将表达式传递给data.table对象以创建新列或修改现有列:

dt <- data.table(x = 1, y = 2)
dynamicDT <- function(...) {
    dt[, list(...)]
}
dynamicDT(z = x + y)

我在期待:

   z
1: 3

但相反,我得到错误:

Error in eval(expr, envir, enclos) : object 'x' not found 

那么我该如何解决这个问题呢?

尝试:

我见过this post,建议使用quotesubstitute,但

> dynamicDT(z = quote(x + y))
Error in `rownames<-`(`*tmp*`, value = paste(format(rn, right = TRUE),  : 
  length of 'dimnames' [1] not equal to array extent

> dynamicDT <- function(...) {
+     dt[, list(substitute(...))]
+ }
> dynamicDT(z = x + y)
Error in prettyNum(.Internal(format(x, trim, digits, nsmall, width, 3L,  : 
  first argument must be atomic

对我不起作用。

2 个答案:

答案 0 :(得分:6)

这应该是David回答的更好的替代方案:

dynamicDT <- function(...) {
 dt[, eval(substitute(...))]
}

dynamicDT(z := x + y)
#   x y z
#1: 1 2 3

答案 1 :(得分:3)

您需要使用eval(parse(text = ))组合。 parse会将字符串转换为表达式,而eval则会对其进行评估。

library(data.table)
dt <- data.table(x = 1, y = 2)
dynamicDT <- function(temp = "") {
  dt[, eval(parse(text = temp))]
}

为了获得您之前想要的输出

dynamicDT("z := x + y")
##    x y z
## 1: 1 2 3

为了获得当前所需的输出

dynamicDT("z = x + y")
## [1] 3

为了解析你可以做的多个参数

dynamicDT('c("a","b") := list(x + y, x - y)')

##   x y a  b
##1: 1 2 3 -1