我注意到当使用不同的赋值操作符时,data.table中有一些不一致(对我来说不一致)的行为。我必须承认我从来没有弄清楚"=“和copy()之间的区别,所以也许我们可以在这里提供一些启发。如果您在下面使用"=“或"<-”而不是copy(),则在更改复制的data.table时,原始data.table也将更改。
请执行以下命令,您就会明白我的意思
library(data.table)
example(data.table)
DT
x y v
1: a 1 42
2: a 3 42
3: a 6 42
4: b 1 4
5: b 3 5
6: b 6 6
7: c 1 7
8: c 3 8
9: c 6 9
DT2 = DT
现在我将更改DT2的v列:
DT2[ ,v:=3L]
x y v
1: a 1 3
2: a 3 3
3: a 6 3
4: b 1 3
5: b 3 3
6: b 6 3
7: c 1 3
8: c 3 3
9: c 6 3
但是看看DT发生了什么:
DT
x y v
1: a 1 3
2: a 3 3
3: a 6 3
4: b 1 3
5: b 3 3
6: b 6 3
7: c 1 3
8: c 3 3
9: c 6 3
它也发生了变化。因此:更改DT2会更改原始DT。如果我使用copy(),就不是这样:
example(data.table) # reset DT
DT3 <- copy(DT)
DT3[, v:= 3L]
x y v
1: a 1 3
2: a 3 3
3: a 6 3
4: b 1 3
5: b 3 3
6: b 6 3
7: c 1 3
8: c 3 3
9: c 6 3
DT
x y v
1: a 1 42
2: a 3 42
3: a 6 42
4: b 1 4
5: b 3 5
6: b 6 6
7: c 1 7
8: c 3 8
9: c 6 9
这是意料之中的行为吗?
发布于 2012-06-25 23:35:32
是。这是预期的行为,并且有很好的记录。
由于data.table
使用对原始对象的引用来实现就地修改,因此速度非常快。
因此,如果您真的想要复制数据,则需要使用 copy(DT)
来自?copy
的文档
通过引用修改data.table,并(不可见地)返回它,以便可以在复合语句中使用它;例如,
setkey(DT,a)[J("foo")]
。如果您需要一个副本,请先获取一个副本(使用DT2=copy(DT)
)。在使用:=
通过引用向列再赋值之前,copy()
有时也很有用。参见?copy
。
另请参阅此问题:Understanding exactly when a data.table is a reference to vs a copy of another
https://stackoverflow.com/questions/11192325
复制相似问题