RMarkdown、R 笔记本和内存管理

Kar*_*agg 3 memory-management r knitr r-markdown

我正在开展一个项目,涉及分析几个非常大的文本文件。我已将项目分成几个部分,每个部分都将在自己的 RMarkdown/R Notebook 中完成,但我遇到了真正的问题。

第一个是,当我正在处理一部分(一个 R 文件)时,我必须定期rm使用变量并重新捕获内存gc()。当我准备好编织文件时,我认为 R 将重新运行所有内容 - 这意味着我需要使用 rm/gc 步骤显式地分块写入。它是否正确?我知道你可以将选项放在cache = TRUE块选项中,但我以前没有这样做过。如果我这样做,所有这些结果是否都保存在内存中(即缓存中)?如果是这样,当我删除变量并重新捕获内存时会发生什么?这是保存演示结果而无需重新运行所有内容的正确方法吗?

谢谢!

Bra*_*sen 5

您的问题是您的代码将所有内容转储到全局环境(您的 Rmd 环境)中。当我处理较大的数据时,我倾向于将分析包装到块内的函数中,而不是像 R 脚本一样编写它。我举一个简单的例子来说明:

将以下内容想象为脚本:

r <- load_big_data() 
train <- r[...]
test <- r[...]
fit <- lm(x ~ y, data = train)
summary(fit)
Run Code Online (Sandbox Code Playgroud)

如果这是您的块,则当模型运行完成时,所有这些变量都会保留在环境中。但是,如果将工作封装在函数中,则一旦函数完成,临时变量通常就会从内存中释放。

r <- load_big_data()
myFun <- function(r) {
  train <- r[...]
  test <- r[...]
  fit <- lm(x ~ y, data = train)
  return(summary(fit))
}
Run Code Online (Sandbox Code Playgroud)

现在,您的工作区中不再有testtrain、 和,而是在工作区中只有 、 和,而这实际上是无成本的fitrmyFun

奖励:您会发现分析时间越长,您就可以重复使用这些函数!

更新

回复:缓存 = TRUE

回答你后续的问题。cache=TRUE将从RDS文件加载而不是重新运行代码块。它可以作为一种有效的工具来最大限度地减少内存使用 - 但您仍然需要记住从工作区中删除数据,因为它是从缓存加载而不是运行的。您应该将其视为节省时间,而不是节省内存,除非您手动清理。

回复: GC()

gc,或“垃圾收集”是 R 本身经常运行的进程的触发器,用于收集和转储它暂时保留但不再使用的内存。R 中的垃圾收集非常好,但gc在更顽固的情况下使用它可以帮助释放内存。Hadley 在这里做了很好的总结: http: //adv-r.had.co.nz/memory.html。话虽如此,它很少是灵丹妙药,通常,如果您觉得需要使用它,您要么需要重新考虑您的方法,要么重新考虑您的硬件,或两者兼而有之。

回复:外部资源

这听起来可能有点轻率,但有时加载另一台比你的机器大得多的机器来完成工作比修复内存泄漏要便宜得多(时间==美元)。示例:具有 16 核和 128GB RAM 的 R5 每小时 1 美元。计算你的时间往往是相当有利可图的。