Reputation: 19793
I am having some trouble getting an eval
within data.table
in R to work with an expression. Here is some code:
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]
Why does including {}
break this?
Upvotes: 4
Views: 655
Reputation: 118779
Issue #376 to trap the {
around :=
has now been implemented in v1.8.11. From NEWS:
o FR #2496 is now implemented to trap and remove the
{
around:=
inj
to obtain desired result. Now,DT[,{`:=`(...)}]
andDT[, {`:=`(...)}, by=(...)]
both work as intended but with a warning. Thanks to Alex for reporting on SO: expression syntax for data.table := in R
Upvotes: 5
Reputation: 721
See the definition of :=
:
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.")
The assignment of a column doesn't happen within a call of :=
--the function itself doesn't do anything besides produce an error. The assignment happens when [.data.table
detectsj
is an expression of the form `:=`(...)
and then sets everything up for a call to the C code. When you enclose expr
in brackets, you're making the first part of the expression {
instead of :=
, which passes by the above detection and eventually results in an evaluation of :=
with arguments c
and d
.
I guess that leads to the question, why do you need to enclose it in { }
?
Upvotes: 7