了解data.table无效的.selfref警告

Pau*_*ens 4 r data.table

我正在尝试找出我在下面的代码中遇到的data.table'invalid .selfref'错误。

library(data.table) 
library(dplyr)
DT <- data.table(aa=1:100, bb=rnorm(n=100), dd=gl(2,100))
DT <- DT %.% group_by(dd, aa) %.% summarize(m=mean(bb))
DT <- DT[, ee := 3]
Run Code Online (Sandbox Code Playgroud)

最后一行引发错误。这里有一个建议,就是将最后一行写为,DT$ee <- 3但并不能真正解释它为什么起作用(和:=不能起作用),并且作为一个初学者data.table用户也不觉得自己是正确的data.table习惯用法。

它与那里的dplyr线有关,显然改变了DT数据表。但是,当我将该行(及其后面的行)更改为该行时,DDT <- DT %.% group_by() ...仍然会从该DT[, ee := 3]行收到selfref错误。

一直在检查各种来源,但那里的所有信息并没有真正减少,因此我仍然感到困惑。

R version 3.1.0 (2014-04-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)

locale:
[1] LC_COLLATE=Dutch_Netherlands.1252  LC_CTYPE=Dutch_Netherlands.1252   
[3] LC_MONETARY=Dutch_Netherlands.1252 LC_NUMERIC=C                      
[5] LC_TIME=Dutch_Netherlands.1252    

attached base packages:
[1] graphics  grDevices utils     datasets  stats     methods   base     

other attached packages:
[1] dplyr_0.2        data.table_1.9.2 ggplot2_1.0.0   

loaded via a namespace (and not attached):
 [1] assertthat_0.1   colorspace_1.2-4 digest_0.6.4     grid_3.1.0      
 [5] gtable_0.1.2     MASS_7.3-31      munsell_0.4.2    parallel_3.1.0  
 [9] plyr_1.8.1       proto_0.3-10     Rcpp_0.11.2      reshape2_1.4    
[13] scales_0.2.4     stringr_0.6.2    tools_3.1.0     
Run Code Online (Sandbox Code Playgroud)

Aru*_*run 5

我只运行了您的代码,然后看到了问题。data.table过度分配列指针的向量(以便稍后通过引用有效地添加列),并且当操作(很可能无意间)删除了该过度分配时,会出现此警告。

让我尝试使用Matt的useR 2014演示文稿中的幻灯片45来解释过度分配。顶部的(蓝色和黄色)框对应于列指针的向量,箭头显示每个指针指向的数据。

左图以图形方式描绘了如何向作品添加(或添加cbind)一列data.framecbind对列进行基本上会导致(较深或较浅的)副本,从而为列指针的向量(以黄色显示)和数据(现在又有一个列)提供了新的位置。

右图显示了创建data.table方式,由于data.table创建时过度分配,开始时会有3个以上的蓝色框。通过使用:=,甚至没有进行浅拷贝。留在原处的列指针向量和下一个未使用的过度分配框用于分配新列。

这是关于区别以及这里的过度分配的含义。

现在,警告提示您所做的任何操作均已消除了此过度分配的情况 -这意味着多余的蓝色框已消失!因此,我们无法再通过引用添加列,直到我们再次过度分配 (这是不必要的,应避免使用,但由于它已经消失了,我们将做下一件最好的事情)。

我的猜测是,您的dplyr语法会以某种方式消除这种过度分配,当您使用该语法时,它会在下一步中捕获,:=data.table在通过引用添加新列之前再次过度分配(这将导致浅表复制)。

如果我这样做data.table

DT <- DT[, list(m=mean(bb)), by=list(dd,aa)]
DT[, ee := 3]
Run Code Online (Sandbox Code Playgroud)

它工作正常。

我现在没有时间研究dplyr或验证正在做什么。

更新:在此处提出了一些必要的更改作为请求请求。