将公式列表应用于R data.table

时间:2016-07-28 19:11:33

标签: r data.table

我有一个data.table和一个公式列表,

DT <- data.table(A = c(1:3), B = c(3:1), C = c(4:6), D = (6:4))
l <- list(f1 = "A + B", f2 = "B + C", f3 = "C - D", f4 = "D / A")

这可以通过

来实现
DT[, ":="(f1 = A + B, f2 = B + C, f3 = C - D, f4 = D / A)]

for (i in 1:length(l)) {
  DT[, eval(names(l)[i]) := eval(parse(text=l[[i]]))]
}

有没有办法在不使用循环的情况下使用l中的信息执行此操作?

# some code
DT
#    A B C D f1 f2 f3       f4
# 1: 1 3 4 6  4  7 -2 6.000000
# 2: 2 2 5 5  4  7  0 2.500000
# 3: 3 1 6 4  4  7  2 1.333333

2 个答案:

答案 0 :(得分:10)

如果您手动构建l,请将其写为

L = quote(`:=`(f1 = A + B, f2 = B + C, f3 = C - D, f4 = D / A))

然后你可以像

一样使用它
DT[, eval(L)]

#    A B C D f1 f2 f3       f4
# 1: 1 3 4 6  4  7 -2 6.000000
# 2: 2 2 5 5  4  7  0 2.500000
# 3: 3 1 6 4  4  7  2 1.333333

这是recommended practice from the FAQ,它解释了......

  

quote()eval()就像其他语言中的宏一样。

答案 1 :(得分:2)

这非常草率,但您可以使用callparsepaste创建表达式,然后调用该表达式:

library(data.table)
DT <- data.table(A = c(1:3), B = c(3:1), C = c(4:6), D = (6:4))
l <- list(f1 = "A + B", f2 = "B + C", f3 = "C - D", f4 = "D / A")
ncall <- call(":=", names(l), 
          parse(text = paste0("list(", paste(l, collapse = ","), ")")))
DT[ , eval(ncall)]
DT
#    A B C D f1 f2 f3         f4
# 1: 1 3 4 6  4  7 -2 6.00000000
# 2: 2 2 5 5  4  7  0 2.50000000
# 3: 3 1 6 4  4  7  2 1.33333333