复制一个数据表列表

5
我有以下情况:
1)一些数据表的列表
2)为了测试目的,我故意想要(深度)复制整个包括数据表在内的列表
3)我想从复制的列表中取出一些元素并添加一个新列。
以下是代码:
library(data.table)
x = data.table(aaa = c(1,2))
y = data.table(bbb = c(1,2))
z = list(x,y)
zz = copy(z)

v = zz[[1]]
v = v[, newColumn := 1]

现在我遇到了以下错误:
Error in `[.data.table`(res, , `:=`(xxx, TRUE)) : 
(converted from warning) Invalid .internal.selfref detected and fixed
by taking a copy of the whole table so that := can add this new column 
by reference. At an earlier point, this data.table has been copied by R 
(or been created manually using structure() or similar). Avoid key<-, 
names<- and attr<- which in R currently (and oddly) may copy the whole 
data.table. Use set* syntax instead to avoid copying: ?set, ?setnames 
and ?setattr. Also, in R<=v3.0.2, list(DT1,DT2) copied the entire DT1 
and DT2 (R's list() used to copy named objects); please upgrade to 
R>v3.0.2 if that is biting. If this message doesn't help, please report 
to datatable-help so the root cause can be fixed.

我不是很清楚R如何处理复制调用并将其传递给data.table,但难道不是这样吗:(?)
如果有人明确使用复制函数,那么他/她应该意识到“按值”和“按引用”的区别。因此,应该向他/她提供对象的真实副本。
因此,我认为不应该出现任何错误,并且我认为出现错误是一个“错误”。这个观点正确吗?
FW

你使用的是哪个版本的 Rdata.table - Simon O'Hanlon
1个回答

6

copy() 是用于复制 data.table 的。你现在正试图将其用于复制一个 list。请尝试使用...

zz <- lapply(z,copy)
zz[[1]][ , newColumn := 1 ]

使用您的原始代码,您会发现将copy()应用于list并不会复制原始的data.table。它们仍然被引用到内存中相同的位置:
library(data.table)
x = data.table(aaa = c(1,2))
y = data.table(bbb = c(1,2))
z = list(x,y)
zz = copy(z)

#  Both zz$x and z$x are the same object:
.Internal(inspect(zz$x))
#  @7fd58a079778 00 NILSXP g1c0 [MARK,NAM(2)] 
.Internal(inspect(z$x))
#  @7fd58a079778 00 NILSXP g1c0 [MARK,NAM(2)] 

这是个好回答,但我对你所说的“copy is for copying data.tables”感到困惑。实际上,你可以在任何 R 对象(包括列表,例如l <- list(1);l2 <- copy(l);.Internal(inspect(l));.Internal(inspect(l2)))上成功使用copy,只是 OP 在这种特定情况下没有正确地将其应用于data.table中。 - David Arenburg
1
我认为我们应该提交一个PR并修复文档 :) - David Arenburg
你需要向 @Arun 请教 copy 的机制是如何工作的,以及它的设计目的和限制。 - Simon O'Hanlon
2
@FabianWerner,copy()旨在与所有对象一起使用,因为它只是从R的C-API中调用duplicate()。然而,我们没有预料到数据表列表的使用情况,因为如果你查看copy(),它会调用alloc.col()。我认为我们需要修复数据表列表的问题,或者限制为原子向量/数据框/数据表和/或文档化它。你能否在GitHub页面上提交一个标题为“列表数据表副本(copy())问题”的问题,并简单地链接到这篇文章?谢谢。 - Arun
3
@Arun: 完成了。(再次感谢您提供这个精彩的软件包 :-) ) - Fabian Werner
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接