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

时间:2011-08-11 21:29:50

标签: r data.table colon-equals

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

2 个答案:

答案 0 :(得分:28)

有两个地方<-可能'重载':

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

第一个将整个x复制到*tmp*,更改该工作副本,然后分配回x。这是最近在r-devel here上讨论的R事件(src / main / eval.c和subassign.c)。听起来有可能将R改为允许包或R本身避免复制到*tmp*,但目前不可能,IIUC。

第二个是Owen的答案所指的,我想。如果您接受可以在j之内通过引用进行分配,那么哪个运算符?根据对Owen的回答的评论,<-中的用户已经使用<<-j,因此我们点击了:=

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

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

通过引用表添加新列,并在每个组中评估每个:=的RHS。 (当:实施组内=时)。


2012年10月更新

自1.8.2开始(2012年7月在CRAN上),实施了:= by group 以添加或更新单个列;即:=的单个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]

迭代多个RHS,设想了一段时间,其中第二个表达式可以使用第一个表达式的结果,尚未实现(FR#1492)。所以这仍然会给出错误"newcol1 not found",需要分两步完成:

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

答案 1 :(得分:16)

我认为没有任何技术原因需要这样做,原因如下::=仅在[...]内使用,因此始终引用它。 [...]遍历表达式树,以查看其中是否有:=

这意味着它并不是真正的运营商,它并没有真正超载;所以他们可以选择他们想要的任何操作员。我想也许它看起来更好?或者更少混淆,因为它显然不是<-

(请注意,如果使用:= <{1}} 之外的[...]则不能<-,因为您实际上无法重载<-<-不评估其左手参数,因此它不知道类型是什么。)