为了澄清一些事情,我想更好地了解在 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
中选择元素所占用内存的引用。 这是正确的吗?
newDT <- DT[x < 11]
也会创建一个副本。在子集创建newDT
后,执行newDT[, b := 5]
。使用tracemem
和.Internal(inspect(.))
是理解此过程的有用工具。 - Arun