data.table引入了:=运算符。为什么不重载< - ?
答案 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}} 之外的[...]
则不能<-
,因为您实际上无法重载<-
。<-
不评估其左手参数,因此它不知道类型是什么。)