将公式列表应用于R data.table
我有一个data.table和一个公式列表将公式列表应用于R data.table,r,data.table,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") 或 是否有一种方法可以使用l中的信息而不使用循环来执行此操作 # some code DT # A B C D f1 f2 f3 f4 # 1: 1 3 4 6
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")
或
是否有一种方法可以使用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
这太草率了,但您可以使用
调用
、解析
和粘贴
创建表达式,然后调用该表达式:
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
库(data.table)
DT如果你是手工构建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
这就是,这解释了
quote()
和eval()
类似于其他语言中的宏
这里的循环有什么问题?并不是所有的循环都不好。我只是想知道是否有避免循环的方法……通常,您可以使用lappy
来避免列上的循环,但正如dayne所说,仅仅使用循环并不总是一件大事。首先,我想应该将它们存储为表达式,而不是文本:L=lappy(L,函数(x)parse(text=x))
。然后,类似于DT[,`:=`(name(L),lappy(L,eval.SD))]
的东西,它可以工作,但我不确定是否符合犹太标准。我想按组计算所有这些公式,但data.table不允许我这样做。我该怎么做?提前谢谢你@Nal rA您可能需要发布一个新问题来澄清。当我尝试它时,它对我很有效:DT[,id:=c(1,1,2)]
然后DT[,eval(L),by=id][]
谢谢!看来我用错了方法。再次感谢你!你的方法能分组评估所有公式吗?谢谢大家!@Dayne您应该能够添加一个“k”术语并按组计算,例如,DT[,eval(ncall),by=list(D)
。我还没有明确测试过这一点,这个示例对分组没有意义,但您当然可以自己测试一些代码。
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