【问题标题】:copy a list of data.tables复制 data.tables 列表
【发布时间】:2015-09-07 18:29:31
【问题描述】:

我有以下情况:

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

标签: r data.table


【解决方案1】:

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 用于复制 data.tables" 而苦恼。实际上,您可以在 any R 对象(包括列表,例如 l &lt;- list(1) ; l2 &lt;- copy(l) ; .Internal(inspect(l)) ; .Internal(inspect(l2)))上成功使用 copy,只是在这种特殊情况下 OP 没有正确使用 data.tables。
  • @DavidArenburg 我也注意到了这一点,但仅仅因为它适用于其他对象并不意味着它是有意的。如果是这种情况,那么文档确实应该更新,因为它指出对于copy(x)xdata.table。所以在我看来,copy() 被定义并记录在data.tables 上以某种方式工作,其他任何事情都是用户风险/错误。
  • 我认为我们应该做一个 PR 并修复文档 :)
  • @FabianWerner, copy() 旨在处理所有对象,因为它只是从 R 的 C-API 对 duplicate() 的调用。但是,我们没有预料到 list-of-data.tables 的用法,就像您查看copy() 一样,它调用了alloc.col()。我认为我们需要修复 data.tables 列表的情况,或限制为原子向量/data.frames/data.tables 和/或记录它。您能否在 github 页面上提出一个标题为“data.tables 问题列表中的复制()”的问题,并简单地链接到这篇文章?谢谢。
  • @Arun:完成。 (再次感谢这个美妙的包裹:-))
猜你喜欢
  • 2021-03-22
  • 2012-08-28
  • 1970-01-01
  • 2019-02-13
  • 2019-12-24
  • 2019-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多