为什么要定义data.table:=而不是重载< – ?

data.table引入了:=运算符。 为什么不过载< – ?

我不认为这是有必要的,因为以下原因:=只用于内部,所以它总是引用。 [...]遍历expression式树来查看是否存在:=

这意味着它不是真的作为一个操作符,它不是真的超载; 所以他们可以挑选他们想要的任何运营商。 我想也许它看起来更好? 或者更less混乱,因为它显然不是<-

(请注意,如果:=[...] 之外使用,则不能<- ,因为实际上不能重载<-<-不计算其左手参数,因此它不知道types是)。

有两个地方可能会被“超载”:

 x[i, j] <- value # 1 x[i, {colname <- value}] # 2 

第一个将整个x复制到*tmp* ,更改该工作副本,并将其分配回x 。 这是一个R的东西(src / main / eval.c和subassign.c)最近在r-devel 这里讨论过。 听起来好像有可能把R改成允许软件包或R本身来避免拷贝到*tmp* ,但目前不可能,IIUC。

第二个是欧文的回答,我想。 如果你接受可以像j那样通过引用进行赋值,那么哪个运算符? 根据Owen的回答, <-<<-已经被j的用户使用过了,所以我们碰到:=

即使[<-没有复制整个x ,我们仍然像:=j所以我们可以做这样的事情:

 DT[,{newcol1:=sum(a) newcol2:=a/newcol1}, by=group] 

通过引用表添加新列,并在每个组内评估每个:=的RHS。 (何时:=在组内执行。)


2012年10月更新

从1.8.2(2012年7月的CRAN)开始,按:= 进行添加或更新单列; 即单个LHS := 。 现在在v1.8.3(在撰写本文时在R-Forge上),可以按组添加多列; 例如,

 DT[, c("newcol1","newcol2") := .(sum(a),sum(b)), by=group] 

或者,也许更优雅:

 DT[,`:=`(newcol1=sum(a), newcol2=sum(b)), by=group] 

但是,第二个expression式可以使用第一个expression式的迭代多重RHS尚未实现( FR#1492 )。 所以这仍然会给出一个错误"newcol1 not found" ,需要分两步完成:

 DT[,`:=`(newcol1=sum(a), newcol2=a/newcol1), by=group]