在data.table中使用eval

时间:2014-11-12 09:50:02

标签: r data.table

我试图将data.table中的eval行为理解为“框架”。

使用以下data.table:

set.seed(1)
foo = data.table(var1=sample(1:3,1000,r=T), var2=rnorm(1000),  var3=sample(letters[1:5],1000,replace = T))

我正在尝试复制这条指令

foo[var1==1 , sum(var2) , by=var3]

使用eval函数:

eval1 = function(s) eval( parse(text=s) ,envir=sys.parent() )

正如您所看到的,测试1和3正在运行,但我不明白哪个是在测试2的eval中设置的“正确”环境:

var_i="var1"
var_j="var2"
var_by="var3"

# test 1 works
foo[eval1(var_i)==1 , sum(var2) , by=var3 ]

# test 2 doesn't work
foo[var1==1 , sum(eval1(var_j)) , by=var3]

# test 3 works
foo[var1==1 , sum(var2) , by=eval1(var_by)]

1 个答案:

答案 0 :(得分:1)

j-exp,在.SD的环境中检查它的变量,代表Subset of Data.SD本身就是data.table,其中包含该组的列。

当你这样做时:

foo[var1 == 1, sum(eval(parse(text=var_j))), by=var3]

直接将j-exp内部优化/替换为sum(var2)。但是sum(eval1(var_j))没有得到优化,并保持不变。

然后,当对每个组进行评估时,它必须找到var2,它在调用函数的parent.frame()中不存在,但是在{ {1}}。例如,让我们这样做:

.SD

它从父框架中找到eval1 <- function(s) eval(parse(text=s), envir=parent.frame()) foo[var1 == 1, { var2 = 1L; eval1(var_j) }, by=var3] # var3 V1 # 1: e 1 # 2: c 1 # 3: a 1 # 4: b 1 # 5: d 1 。也就是说,我们必须指向正确的评估环境,并使用值= var2的附加参数。

.SD