data.table updates" unlinked" setkey之后的变量,为什么?

时间:2014-10-09 10:52:28

标签: r data.table

来自 data.table 包的奇怪行为,请尝试下面的代码,为什么排序会在 x 中发生变化?

#R version 3.1.0 (2014-04-10)
#data.table_1.9.2 same error for (data.table_1.9.4)

require(data.table)

#dummy data
dat <- fread("A,B
6,7
4,5
1,2
3,4
0,2")

#get x and y
x <- dat$A
y <- dat[,A]

#compare - x and y, same.
x # [1] 6 4 1 3 0
y # [1] 6 4 1 3 0
all(x==y) # [1] TRUE

#Set key on column A
setkey(dat,A)

#compare - x is not same as y anymore!
x # [1] 0 1 3 4 6
y # [1] 6 4 1 3 0
all(x==y) # [1] FALSE

1 个答案:

答案 0 :(得分:1)

扩展我的评论:

完成后:

require(data.table)
dat <- fread("A,B
6,7
4,5
1,2
3,4
0,2")

# get x and y
x <- dat$A
y <- dat[,A]

如果你这样做:

.Internal(inspect(x))
# @7fa677439e40 13 INTSXP g0c3 [NAM(2)] (len=5, tl=5) 6,4,1,3,0
.Internal(inspect(dat$A))
# @7fa677439e40 13 INTSXP g0c3 [NAM(2)] (len=5, tl=5) 6,4,1,3,0

您可以看到的地址@7fa677439e40相同(您的设备上的值本身会有所不同)。这是因为当我们使用$运算符提取整个列并将其分配给变量时,R并不真正复制数据。它只在绝对必要时复制。

对第二种情况做同样的事情:

.Internal(inspect(y))
# @7fa677455248 13 INTSXP g0c3 [NAM(2)] (len=5, tl=5) 6,4,1,3,0
.Internal(inspect(dat)) # pasting the first 3 lines of output here
# @7fa674a0be00 19 VECSXP g0c7 [OBJ,NAM(2),ATT] (len=2, tl=100)
#   @7fa677439e40 13 INTSXP g0c3 [NAM(2)] (len=5, tl=5) 6,4,1,3,0 <~~~~~~~ 
#   @7fa677439e88 13 INTSXP g0c3 [NAM(2)] (len=5, tl=5) 7,5,2,4,2

ydat[, A]的地址(请参阅箭头标记)不相同。这是因为data.table子集已经创建了一个副本。在R中,dat$Adat[["A"]]在这些情况下都不会复制(当你不想制作不必要的副本时也很好知道!)。

如果您有更多问题,请回信。

HTH

有关copy-on-modify的更多信息。