我在R中使用data.table
包。其中,data.table导致表通过引用传递。 Data.table还支持插入或删除byRef列,因此你可以做这样的事情......
library('data.table')
AddSquares<-function(DT){
DT[,x2:=(x*x)]
}
DT<-data.table(x=1:3)
AddSquares(DT)
DT
x x2
1: 1 1
2: 2 4
3: 3 9
x2是在DT byRef中创建的,所以我没有必要返回修改后的表。容易脱皮。很遗憾,data.table不支持插入或删除行 byRef,因此会发生以下情况......
StripEvens<-function(DT){
DT <- DT[x %% 2 != 0]
}
StripEvens(DT)
DT
x x2
1: 1 1
2: 2 4
3: 3 9
<-
运算符按值运算,因此它在函数内创建DT的副本。如果我从那时起不再返回DT,那么它就会被销毁掉#39;当函数调用结束时。如果我做返回DT,那么我可以找回一个看起来像我想要的方式的表,但我已经通过制作一个副本来完成,这可能也是通过byVal。
所以这就是问题所在。一旦DT传递给我的函数byRef,我如何让R继续在DT byRef上工作?同样,如何让R将函数内部的DT视为对函数外部DT引用的同一对象的引用?这甚至可能吗?
答案 0 :(得分:3)
这将以names(x) <- letters
的方式执行此类操作。也就是说,它看起来像是参考,但它并不是真的。如果您关心语义而不是对象的副本是否被创建,那么您可以执行以下操作:
library(data.table)
DT1 <- data.table(x=1:3)
StripEvens<-function(DT) {
x <- substitute(DT)
if(is.name(x)) {
DT.ext <- get(as.character(x), parent.frame(), inherits=FALSE)
if(identical(DT, DT.ext)) {
assign(as.character(x), DT[x %% 2 != 0], envir=parent.frame())
} }
return(invisible(NULL))
}
StripEvens(DT1)
DT1
产地:
x
1: 1
2: 3
这不是完全健壮的(即如果对象实际上不在父框架中则中断,等等),但是可以通过一点工作使其变得健壮。更大的问题是对象实际上并未通过引用进行修改,而是被复制,修改和替换。正如其他人所指出的那样,除非你用C编写函数,否则实际的参考修改是不可能的。