Mat*_*wle 29
有两个地方<-可能会"超载":
x[i, j] <- value # 1
x[i, {colname <- value}] # 2
Run Code Online (Sandbox Code Playgroud)
第一个拷贝整个的x到*tmp*,改变了工作副本,并分配回x.这是r-devel最近在这里讨论的R事件(src/main/eval.c和subassign.c).这听起来似乎可以改变R以允许包或R本身避免该副本*tmp*,但目前不可能,IIUC.
第二个是欧文的回答,我想.如果您接受可以通过引用进行分配j,那么哪个运算符?根据对Owen的回答的评论,<-并且<<-已经被用户使用j,所以我们点击了:=.
即使[<-没有复制整个x,我们仍然喜欢:=,j所以我们可以做这样的事情:
DT[,{newcol1:=sum(a)
newcol2:=a/newcol1}, by=group]
Run Code Online (Sandbox Code Playgroud)
通过引用表添加新列的位置,并:=在每个组中评估每个列的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]
Run Code Online (Sandbox Code Playgroud)
或者,也许更优雅:
DT[,`:=`(newcol1=sum(a),
newcol2=sum(b)), by=group]
Run Code Online (Sandbox Code Playgroud)
但设想一段时间的迭代多重RHS,其中第二个表达式可以使用第一个表达式的结果,尚未实现(FR#1492).所以这仍然会出错"newcol1 not found",需要分两步完成:
DT[,`:=`(newcol1=sum(a),
newcol2=a/newcol1), by=group]
Run Code Online (Sandbox Code Playgroud)
Owe*_*wen 16
我不认为有任何技术原因这是必要的,原因如下::=只在内部使用,[...]所以总是引用它.[...]通过表达式树来查看是否:=在其中.
这意味着它并没有真正作为一个运营商,它并没有真正超载; 所以他们可以选择他们想要的任何操作员.我想也许它看起来更好?或者更少混淆,因为它显然不是<-?
(注意,如果:=在它之外使用[...]它是不可能的<-,因为你实际上不能超载<-.<-不评估它的左手参数,因此它不知道类型是什么).