[英]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.