我似乎发现了一种情况,即data.table的引用更新无法按预期工作,并在Understanding exactly when a data.table is a reference to (vs a copy of) another data.table中进行了描述。
如果从Rdata文件加载data.table并通过:=
引用进行更新,则会隐式复制data.table(即更改内存地址)。只要您在同一环境中进行更新,这就有效。
但是,如果在函数内部进行更新(例如f(dt)),则data.table dt
不会在调用环境中的函数外部更改,因为它是在函数内部复制的。 / p>
这是一个小例子
# function definition
f1 <- function(dt,dtj){
dt[,c("C","D"):=(dt[dt.j,nomatch=0][,list(C,D)])]
}
# create, save, delete and then load from file
dt <- data.table(A=c("A","A","B"),B=1:3,key=c("A"))
dt.j <- data.table(A=c("A","B","C"),C=5:7,D=c("a","a","b"))
save(dt,file="~/test.Rdata")
rm(dt)
load(file="~/test.Rdata")
address(dt)
f1(dt,dt.j)
address(dt)
dt
dt的地址与data.table保持一致。
该功能的代码没有任何问题。如果省略该功能并只进行更新,它可以工作,但它会更改data.table的地址
address(dt)
dt[,c("C","D"):=(dt[dt.j,nomatch=0][,list(C,D)])]
address(dt)
dt
我可以通过在加载后复制data.table来解决这个问题。
我想知道的是除了上面提到的还有其他情况,data.table显示了这种行为。
以下是有关R的信息(我也可以在Windows机器上复制此行为)
R version 3.2.2 (2015-08-14)
Platform: x86_64-redhat-linux-gnu (64-bit)
Running under: Generic 22 (Generic)
locale:
[1] LC_CTYPE=de_DE.UTF-8 LC_NUMERIC=C LC_TIME=de_DE.utf8
[4] LC_COLLATE=de_DE.UTF-8 LC_MONETARY=de_DE.utf8 LC_MESSAGES=de_DE.UTF-8
[7] LC_PAPER=de_DE.utf8 LC_NAME=C LC_ADDRESS=C
[10] LC_TELEPHONE=C LC_MEASUREMENT=de_DE.utf8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] data.table_1.9.6
loaded via a namespace (and not attached):
[1] tools_3.2.2 chron_2.3-47