R 修改函数中变量的内存有效方法

R 修改函数中变量的内存有效方法,r,memory,memory-management,global,R,Memory,Memory Management,Global,问题 我想写一个函数,修改一个大矩阵x的每一列: 因为x非常大,我想“就地”修改它,即不创建副本。然而,我的理解是,在R中,函数是“修改时复制”。换句话说,如果我在函数f中修改x,R将复制x 建议的解决方案(更新:无效!有关详细信息,请参阅下面的答案)。 因此,似乎最好的解决方案是修改全局变量,即 f = function(x){ x = deparse(substitute(x)) x = get(x, envir = globalenv()) # do somethi

问题

我想写一个函数,修改一个大矩阵x的每一列:

因为x非常大,我想“就地”修改它,即不创建副本。然而,我的理解是,在R中,函数是“修改时复制”。换句话说,如果我在函数f中修改x,R将复制x

建议的解决方案(更新:无效!有关详细信息,请参阅下面的答案)。

因此,似乎最好的解决方案是修改全局变量,即

f = function(x){
    x = deparse(substitute(x))
    x = get(x, envir = globalenv())
    # do something to x
}
问题

然而,SO上的人对将全局变量传递到R中的函数非常消极。有些人甚至因为问这个问题而被否决


我的问题是:在R中这样做的最佳方式是什么?

这里已经讨论了这个问题:

你的第二种方法并不能真正解决问题。这是我用mem_used()的结果运行的测试

库(pryr)
mem_used()
#41.3 MB

我很确定您提出的解决方案仍然会在f中创建一个副本,但我很想测试它。
data.table
包。常规R函数中的赋值仍然会生成中间临时副本。避免这种情况的唯一方法是重新定义[我很好奇,哪些问题被否决了,因为“将全局变量传递到函数中”…除了最严格的环境之外,这是不可避免的。相反,我可以相信:访问(甚至修改)函数中的全局变量,而不是通过违反词法范围来传递。有时纯函数方法可能效率低下,但不受控制的副作用使调试和代码维护极其困难。不幸的是,正如@42-所建议的,R几乎完全是关于按副本引用和按写副本,
data.table
是一个显著的例外。
data.table
在这种情况下会很有帮助。例如:在您的解决方案中,修改所选列的位置
cols@Tung,我很好奇使用了多少内存?我的理解是data.table在内存中创建了两个对象(原始数据表和平均缩放表),然后将其中一列替换为另一列?还是在计算新的以平均值为中心的值后立即替换原始表中的每一列?很高兴知道。我将更新我的问题以反映这一点。谢谢!
f = function(x){
    x = deparse(substitute(x))
    x = get(x, envir = globalenv())
    # do something to x
}
library(pryr)
mem_used()
#41.3 MB

x <- matrix(1:1000000000, ncol=1000)
mem_used()
#4.04GB


f2<- function(x){
  print(mem_used())
  x = deparse(substitute(x))
  print(mem_used())
  x = get(x, envir = globalenv())
  x<- x+1
  print(mem_used())
  x
}

x <- f2(x)
#4.04 GB
#4.04 GB
#12 GB
mem_used()
#8.04GB