【发布时间】:2013-03-31 04:37:37
【问题描述】:
只是为了自己清理一些东西,我想更好地了解何时制作副本以及何时不在data.table 中。正如这个问题所指出的Understanding exactly when a data.table is a reference to (vs a copy of) another data.table,如果你只是简单地运行以下命令,那么你最终会修改原来的:
library(data.table)
DT <- data.table(a=c(1,2), b=c(11,12))
print(DT)
# a b
# [1,] 1 11
# [2,] 2 12
newDT <- DT # reference, not copy
newDT[1, a := 100] # modify new DT
print(DT) # DT is modified too.
# a b
# [1,] 100 11
# [2,] 2 12
但是,如果这样做(例如),那么您最终会修改新版本:
DT = data.table(a=1:10)
DT
a
1: 1
2: 2
3: 3
4: 4
5: 5
6: 6
7: 7
8: 8
9: 9
10: 10
newDT = DT[a<11]
newDT
a
1: 1
2: 2
3: 3
4: 4
5: 5
6: 6
7: 7
8: 8
9: 9
10: 10
newDT[1:5,a:=0L]
newDT
a
1: 0
2: 0
3: 0
4: 0
5: 0
6: 6
7: 7
8: 8
9: 9
10: 10
DT
a
1: 1
2: 2
3: 3
4: 4
5: 5
6: 6
7: 7
8: 8
9: 9
10: 10
据我了解,发生这种情况的原因是,当您执行 i 语句时,data.table 返回一个全新的表,而不是对旧 data.table 的选择元素占用的内存的引用.这是正确的和真实的吗?
编辑:对不起,我的意思是 i 不是 j(在上面进行了更改)
【问题讨论】:
-
即使
newDT <- DT[x < 11]也会创建一个副本。在通过子集创建newDT之后执行newDT[, b := 5]。使用tracemem和.Internal(inspect(.))是了解这一点的信息工具。 -
@Arun:对不起,我不确定我是否理解你的意思..你能解释一下你指的是什么吗?你的意思是说第一个例子和第二个例子一样吗?在这种情况下是的 - 这是真的。我只是想要一个单独的例子来说明清楚。
-
当然,你能解释一下你在这里指的是哪个
j声明:As I understand it, the reason this happens is because when you execute a j statement,只是为了确定。我会用我当时谈到的内容写一个答案。 -
mnel回答的第一行基本上就是我之前的问题想搞清楚的,现在算了吧。
标签: r data.table