我在R中eval
内data.table
处理表达式时遇到了一些问题。这是一些代码:
dtb = data.table(a=1:100, b=100:1, id=1:10)
dtb[,`:=`(c=a+b, d=a/b),by=id] #this works fine
expr = expression({`:=`(c=a+b, d=a/b)}) #try to couch everything in an expression
dtb[,eval(expr),by=id] #this does not work
Error in `:=`(c = a + b, d = a/b) :
unused argument(s) (c = a + b, d = a/b)
expr = expression(`:=`(c=a+b, d=a/b)) #this works fine
dtb[,eval(expr),by=id]
为什么包含{}
会破坏这个?
答案 0 :(得分:7)
请参阅:=
的定义:
function (LHS, RHS)
stop(":= is defined for use in j only, and (currently) only once; i.e., DT[i,col:=1L] and DT[,newcol:=sum(colB),by=colA] are ok, but not DT[i,col]:=1L, not DT[i]$col:=1L and not DT[,{newcol1:=1L;newcol2:=2L}]. Please see help(\":=\"). Check is.data.table(DT) is TRUE.")
在:=
的调用中不会发生列的赋值 - 除了产生错误之外,函数本身不会执行任何操作。当[.data.table
检测到j
是`:=`(...)
形式的表达式然后将所有内容设置为调用C代码时,就会发生分配。当您将expr
括在括号中时,您正在制作表达式{
的第一部分而不是:=
,它通过上述检测并最终得出{{1}的评估结果参数:=
和c
。
我想这会引出一个问题,为什么需要将其括在d
中?
答案 1 :(得分:5)
Issue #376来{
:=
陷阱{
。来自NEWS:
o FR#2496现已实施,用于捕获并移除
:=
中j
周围的DT[,{`:=`(...)}]
以获得所需结果。现在,DT[, {`:=`(...)}, by=(...)]
和{{1}}都按预期工作,但有警告。感谢Alex报告SO:expression syntax for data.table := in R