我可以通过引用得到()一个R全局环境变量吗?

时间:2013-03-30 02:42:38

标签: r

我有21个全局环境变量,每个变量都包含大量数据。我希望通过函数内的引用来访问这些变量,但我想对它们的名称进行参数化,例如,如果我有SPdata,NEdata,FRdata等...... 21个变量,我想知道如何通过传递在函数内访问它们只有“国家名称”(即“SP”,“NE”,“FR”等)没有必须创建一个副本(因为它们的大小都超过300微米)。副本(我的数据大小效率不高)。我可以这样做吗?我目前正在使用无处不在的

cData <- get(paste(cCode, "data", sep = "")) 

是的我知道我应该将它们全部放入全局环境的列表中,但现在已经太晚了,我不想重构所有代码。只是我的“获取”变得内存效率低下,循环中的多次访问可能会很慢。我可以例如访问每个变量,就像它在列表中一样吗?

我应该使用countryData = list(SPdata,NEdata,FRdata..etc),使用countryData [[paste(cCode,“data”,sep =“”)]来访问它们,但现在已经太晚了。

我应该补充说,我确实打算在函数中更改某些值,并且get()会在更改时进行复制,这可以从下面的不同地址中看到。

> .Internal(inspect(a))
@101b7bcf8 14 REALSXP g0c1 [NAM(2)] (len=1, tl=0) 1
> g <- function() {x <- get("a"); x; x <- 2; .Internal(inspect(x))}
> g()
@101cea648 14 REALSXP g0c1 [NAM(2)] (len=1, tl=0) 2
> 

2 个答案:

答案 0 :(得分:5)

get不会生成副本。例如,在下面的代码中,我们看到x 不是 a.1的副本,因为它位于同一地址,即0x00000000077a0010

> a.1 <- 1:1000000
> .Internal(inspect(a.1))
@0x00000000077a0010 13 INTSXP g0c7 [NAM(1)] (len=1000000, tl=0) 1,2,3,4,5,...
> g <- function() { x <- get("a.1"); .Internal(inspect(x)); max(x) }
> g()
@0x00000000077a0010 13 INTSXP g0c7 [NAM(2)] (len=1000000, tl=0) 1,2,3,4,5,...
[1] 1000000

如果您修改变量(追加是一种修改),那么它将被复制。此处x始于0x00000000075b95d8,但经过修改后被复制到0x000000000744d8e0,并且在被追加后再次被复制到0x000000000754c5e8

> n <- 10000
> x <- 1:n
> .Internal(inspect(x))
@0x00000000075b95d8 13 INTSXP g0c7 [NAM(1)] (len=10000, tl=0) 1,2,3,4,5,...
> f <- function() {
+ .GlobalEnv$x[[n]] <- 0
+ .Internal(inspect(x))
+ x <<- c(x, 0)
+ .Internal(inspect(x))
+ }
> f()
@0x000000000744d8e0 14 REALSXP g0c7 [NAM(1)] (len=10000, tl=0) 1,2,3,4,5,...
@0x000000000754c5e8 14 REALSXP g0c7 [NAM(1)] (len=10001, tl=0) 1,2,3,4,5,...

上面我们在函数中修改了全局变量,但即使我们在函数之外完成了它,它仍然会被复制。

答案 1 :(得分:4)

快速的:

  • R语义是“写入时复制”,因此如果您不改变这些变量的内容,则不会制作副本

  • R有内存分析,你真的确定要制作副本吗?有关内存分析的基础知识,请参阅“编写R扩展”。

  • 如果您确实要确保复制这些内容,可以通过强制使用外部指针来防止这种情况,无论是使用XPtr对象还是使用部署外部指针(如bigmemory)的包装器。