在R中传递大型对象的内存高效方法

3

我有一个函数需要访问其父环境中的变量(即调用该函数的范围)。该变量在内存方面很大,因此我不想通过按值传递将其传递给被调用的函数。是否有一种标准方法来实现这一点,而不是在全局范围内声明变量?例如:

g <- function (a, b) { #do stuff}

f <- function(x) {
    y <- 3 #but in my program y is very large
    g(x, y)
}

我希望在g()函数中访问变量y。如下所示:

g <- function (a) { a+y }

f <- function(x) {
    y <- 3 #but in my program y is very large
    g(x)
}

这个可能吗?

谢谢


6
你尝试过这个吗?只有在你改变它时,y 才会被复制。 - Joshua Ulrich
1
不错的问题。我在重写了一堆代码以按照你的建议执行后发现没有明显的加速。 - Aaron left Stack Overflow
你如何检查值是否已被复制,或者变量只是指向内存中的那个地址?我理解你的意思,但我只是好奇在R中如何实现这一点。 - Alex
1个回答

7
在全局作用域中“声明变量”没有任何优势,而且在R中这可能甚至不可能实现,具体取决于你的意思。你当然可以使用第二种形式。导致对象重复或甚至三次复制的操作是赋值。您需要更详细地描述您试图通过代码说明的内容:y < - 3。在仅访问嵌套框架中名为“y”的对象的函数内部通常不需要这样做。
将变量存储在已声明环境中有时会提高访问效率,但据我了解,效率是指使用哈希表提高速度。一个环境中访问项目的方式与访问列表元素的方式相同:
> evn <- new.env()
> evn$a <- rnorm(100000)
> ls(evn)
[1] "a"
> length(evn$a)
[1] 100000

大内存项目可能提供这方面的设施:http://www.bigmemory.org/。它和Lumley的biglm可以帮助处理评论中提到的大数据集。

谢谢,这非常有帮助。特别是我的函数运行回归,数据框中大约有3000万行,这就是我的y。我猜测lm()不会以任何方式修改数据,所以传递它应该没问题。 - Alex
2
但它将创建一个残差向量和另一个长度为3000万的线性预测器向量。有时人们使用lm.fit会获得更好的性能,但在其他情况下可能需要对数据进行采样。subset函数可以很好地完成这项工作。 - IRTFM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接