【发布时间】:2013-02-01 13:43:37
【问题描述】:
我的问题
如果将对象x 传递给修改它的函数f,R 将在f 的环境中创建x 的修改本地副本,而不是更改原始对象(由于副本变化原则)。但是,我有一种情况,x 非常大,一旦传递给f 就不需要它,所以我想避免在调用f 时存储x 的原始副本。有没有聪明的方法来实现这一点?
f 是一个未知函数,可能由不太聪明的用户提供。
我目前的解决方案
到目前为止,我最好的方法是将 x 包装在一个函数 forget 中,该函数对 x 进行新的本地引用,称为 y,删除工作区中的原始引用,然后传递新的参考。问题是我不确定它是否能完成我想要的,它只适用于globalenv(),这在我目前的情况下是一个交易破坏者。
forget <- function(x){
y <- x
# x and y now refers to the same object, which has not yet been copied
print(tracemem(y))
rm(list=deparse(substitute(x)), envir=globalenv())
# The outside reference is now removed so modifying `y`
# should no longer result in a copy (other than the
# intermediate copy produced in the assigment)
y
}
f <- function(x){
print(tracemem(x))
x[2] <- 9000.1
x
}
这里是调用上述函数的一个例子。
> a <- 1:3
> tracemem(a)
[1] "<0x2ac1028>"
> b <- f(forget(a))
[1] "<0x2ac1028>"
[1] "<0x2ac1028>"
tracemem[0x2ac1028 -> 0x2ac1e78]: f
tracemem[0x2ac1e78 -> 0x308f7a0]: f
> tracemem(b)
[1] "<0x308f7a0>"
> b
[1] 1.0 9000.1 3.0
> a
Error: object 'a' not found
底线
我正在做我希望我做的事吗?有更好的方法吗?
【问题讨论】:
-
我很确定有某种
rm(x,.GlobalEnv)的东西,因为许多R工具可以让您指定执行命令的环境。但是让我问一下:如果x只在你的函数中使用,你为什么首先将它加载到你的工作区中?为什么不在函数内部创建或加载x? -
你说得对,可能需要一些背景知识。我有一个数据集,我反复想从中提取两个随机子集:一个设计集
x和一个测试集y。基于设计集,我想定义一个应用于两个集的转换。然后我想将设计集x发送到用户提供的模型拟合函数f以获得模型m。然后我想将m应用于y并计算性能。由于f可能会占用大量内存,而x很大,所以我认为在调用f之前丢弃我不需要的任何内容会有所帮助。
标签: r memory-management