简体   繁体   English

在data.table中使用eval

[英]using eval in data.table

I'm trying to understand the behaviour of eval in a data.table as a "frame". 我试图将data.table中的eval行为理解为“框架”。

With following data.table: 使用以下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))

I'm trying to replicate this instruction 我正试图复制这条指令

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

using a function of eval: 使用eval函数:

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

As you can see, test 1 and 3 are working, but I don't understand which is the "correct" envir to set in eval for test 2: 正如您所看到的,测试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)]

The j-exp , checks for it's variables in the environment of .SD , which stands for Subset of Data . j-exp.SD的环境中检查它的变量,它代表Subset of Data .SD is itself a data.table that holds the columns for that group . .SD本身就是一个data.table ,用于保存该的列。

When you do: 当你这样做时:

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

directly, the j-exp gets internally optimised/replaced to sum(var2) . 直接地, j-exp内部优化/替换为sum(var2) But sum(eval1(var_j)) doesn't get optimised, and stays as it is. 但是sum(eval1(var_j))没有得到优化,并保持不变。

Then when it gets evaluated for each group, it'll have to find var2 , which doesn't exist in the parent.frame() from where the function is called, but in .SD . 然后,当对每个组进行评估时,它必须找到var2 ,它在调用函数的parent.frame()中不存在,但在.SD As an example, let's do this: 举个例子,我们这样做:

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

It find var2 from it's parent frame. 它从它的父框架中找到var2 That is, we have to point to the right environment to evaluate in, with an additional argument with value = .SD . 也就是说,我们必须指向正确的评估环境,并使用值= .SD的附加参数。

eval1 <- function(s, env) eval(parse(text=s), envir = env, enclos = parent.frame())
foo[var1 == 1, sum(eval1(var_j, .SD)), by=var3]
#    var3         V1
# 1:    e  11.178035
# 2:    c -12.236446
# 3:    a  -8.984715
# 4:    b  -2.739386
# 5:    d  -1.159506

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM