12

我有 12 data.frames 可以使用。它们是相似的,我必须对每一个都做同样的处理,所以我写了一个函数,它接受 a data.frame,处理它,然后返回 a data.frame。这行得通。但我担心我正在绕过一个非常大的结构。我可能正在制作临时副本(是吗?)这效率不高。避免绕过的最佳方法是什么data.frame

doSomething <- function(df) {
  // do something with the data frame, df
  return(df)
}
4

3 回答 3

10

实际上,您正在传递对象并使用一些内存。但我不认为你可以在不传递对象的情况下对 R 中的对象进行操作。即使您没有创建函数并在函数之外进行操作,R 的行为也基本相同。

看到这一点的最好方法是建立一个例子。如果您在 Windows 中,请打开 Windows 任务管理器。如果您在 Linux 中打开终端窗口并运行 top 命令。在此示例中,我将假设 Windows。在 R 中运行以下命令:

col1<-rnorm(1000000,0,1)
col2<-rnorm(1000000,1,2)
myframe<-data.frame(col1,col2)

rm(col1)
rm(col2)
gc()

这会创建一对名为 col1 和 col2 的向量,然后将它们组合成一个名为 myframe 的数据帧。然后它会丢弃向量并强制垃圾收集运行。在 Windows 任务管理器中查看 Rgui.exe 任务的内存使用情况。当我启动 R 时,它使用大约 19 兆内存。运行上述命令后,我的机器对 R 的使用量不到 35 兆。

现在试试这个:

myframe<-myframe+1

您对 R 的内存使用量应该超过 144 兆。如果您使用 gc() 强制垃圾收集,您将看到它回落到大约 35 兆。要使用函数尝试此操作,您可以执行以下操作:

doSomething <- function(df) {
    df<-df+1-1
return(df)
}
myframe<-doSomething(myframe)

当您运行上面的代码时,内存使用量将跃升至 160 兆左右。运行 gc() 会将其降回 35 兆。

那么如何看待这一切呢?好吧,在函数之外执行操作(就内存而言)并不比在函数中执行操作更有效。垃圾收集清理东西真的很好。你应该强制 gc() 运行吗?可能不会因为它会根据需要自动运行,我只是在上面运行它以显示它如何影响内存使用。

我希望这会有所帮助!

于 2009-03-04T21:28:26.303 回答
9

我不是 R 专家,但大多数语言对大对象使用引用计数方案。在您修改对象的副本之前,不会生成对象数据的副本。如果您的函数仅读取数据(即用于分析),则不应进行复制。

于 2009-03-04T21:41:41.980 回答
0

我在寻找其他东西时遇到了这个问题,而且它已经过时了-所以我现在只提供一个简短的答案(如果您想获得更多解释,请发表评论)。

您可以在 R 中传递环境,其中包含从 1 到所有变量的任何位置。但可能你不需要担心它。

[你也可以对类做类似的事情。我目前只了解如何将类用于多态函数 - 并注意有不止 1 个类系统正在运行。]

于 2013-05-01T19:34:15.980 回答