【问题标题】:Why has data.table defined := rather than overloading <-?为什么定义 data.table := 而不是重载 <-?
【发布时间】:2011-10-25 09:00:48
【问题描述】:

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

【问题讨论】:

  • 让我猜猜:向帕斯卡致敬!!!
  • 我猜!我们不能选择任何运算符,只是(幸运的是)R 允许定义 :=。否则我们可以玩得开心并定义 +=、-=、~= 等 :)
  • 有人能解释一下“重载
  • @Michael "Overloading" 粗略地说意味着用另一个工作方式不同的&lt;- 版本替换&lt;-。以某种方式使&lt;- 以不同的方式工作。相反,我们使用了一个新的运算符:=,以便清楚地了解其他原因。 R 中几乎所有东西都是函数,甚至是 &lt;-[ 等。
  • @Michael 但正如欧文在 cmets 中指出的那样,“重载”在技术上可能是不正确的。我的意思是松散的。

标签: r data.table colon-equals


【解决方案1】:

&lt;- 有两个地方可能被“重载”:

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。

我认为第二个是欧文的回答所指的。如果您接受可以像这样在j 中通过引用进行赋值,那么哪个运算符?根据对欧文回答的评论,&lt;-&lt;&lt;- 已被j 中的用户使用,因此我们找到了:=

即使[&lt;- 没有复制整个x,我们仍然喜欢:= in 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]

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

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

【讨论】:

  • 只是一件小事,x[i, j] &lt;- value 实际上并没有重载&lt;-,而是&lt;- 通过委托给[&lt;-(基于表达式,而不是值类型)来做它总是做的事情)。
  • @Owen 啊,是的,好点。编辑并添加了关于“重载”的引号。
【解决方案2】:

我认为这没有任何技术原因是必要的,原因如下::= 仅在 [...] 内部使用,所以它总是被引用。 [...] 遍历表达式树以查看 := 是否在其中。

这意味着它并没有真正充当运算符,也没有真正重载;所以他们几乎可以选择任何他们想要的操作员。我想也许它看起来更好?或者不那么令人困惑,因为它显然不是&lt;-

(请注意,如果在[...]外部 使用:=,则它不可能是&lt;-,因为您实际上不能重载&lt;-&lt;- 不评估它的左手参数,所以它不知道类型是什么)。

【讨论】:

  • 是的,差不多就是这样。我们实际上首先尝试了
猜你喜欢
  • 1970-01-01
  • 2011-02-09
  • 2022-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-26
  • 2021-04-26
  • 1970-01-01
相关资源
最近更新 更多