我正在编写一个函数,除其他外,将输入强制转换为data.table.
library(data.table)
df <- data.frame(id = 1:10)
f <- function(df){setDT(df)}
f(df)
df[, temp := 1]
Run Code Online (Sandbox Code Playgroud)
但是,最后一个命令输出以下警告:
警告消息:在
[.data.table
(DF,:=
(温度,1)):检测到并通过取整个表的副本固定无效.internal.selfref使得:=可以通过参考添加此新列.在较早的时候,此data.table已被R复制(或使用structure()或类似方法手动创建).避免使用键< - ,名称< - 和attr < - 当前(并且奇怪地)在R中可以复制整个data.table.使用set*语法来避免复制:?set,?setnames和?setattr.另外,在R <= v3.0.2中,列表(DT1,DT2)复制了整个DT1和DT2(用于复制命名对象的R列表()); 如果是咬人,请升级到R> v3.0.2.如果此消息没有帮助,请向datatable-help报告,以便修复根本原因.
我正在使用data.table和R 3.1.1的v1.9.3.这是否意味着df
在某些时候复制?如何避免这种警告?
编辑:setDT
实际使用NSE 的代码.所以这似乎有效:
df1 <- data.frame(id = 1:10)
f <- function(df){eval(substitute(setDT(df)),parent.frame())}
f(df1)
df1[, temp := 1]
Run Code Online (Sandbox Code Playgroud)
看来我可以做其他的东西在函数内DF f
像
df1 <- data.frame(id = 1:10)
f <- function(df){
eval(substitute(setDT(df)),parent.frame())
df[, temp := 1]
}
f(df1)
Run Code Online (Sandbox Code Playgroud)
这是正确的方法吗?
检查这个玩具代码:
> x <- data.table(a = 1:2)
> foo <- function(z) { z[, b:=3:4] }
> y <- foo(x)
> x[]
a b
1: 1 3
2: 2 4
Run Code Online (Sandbox Code Playgroud)
看来 data.table 是通过引用传递的。这是故意的吗?这有记录吗?我确实阅读了文档,但找不到提及此行为。
我并不是在询问 R 的文档化参考语义(在:=
以及set***
其他一些文档中)。我问 data.table 完整对象是否应该作为函数参数通过引用传递。
编辑:根据@Oliver 的回答,这里有一些更奇怪的例子。
> dt<- data.table(a=1:2)
> attr(dt, ".internal.selfref")
<pointer: 0x564776a93e88>
> address(dt)
[1] "0x5647bc0f6c50"
>
> ff<-function(x) { x[, b:=3:4]; print(address(x)); print(attr(dt, ".internal.selfref")) }
> ff(dt)
[1] "0x5647bc0f6c50"
<pointer: 0x564776a93e88>
Run Code Online (Sandbox Code Playgroud)
因此,不仅.internal.selfref
与调用者的 dt 副本相同,而且地址也相同。这确实是同一个物体。(我认为)。 …