【问题标题】:RMarkdown, R Notebooks, and Memory ManagementRMarkdown、R Notebooks 和内存管理
【发布时间】:2022-01-04 21:02:55
【问题描述】:

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

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

谢谢!

【问题讨论】:

    标签: r memory-management r-markdown knitr


    【解决方案1】:

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

    将以下内容想象成一个脚本:

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

    如果这是您的块,当您的模型运行完成时,所有这些变量都会留在环境中。然而,如果你将你的工作封装在一个函数中,一旦函数完成,中间变量通常会从内存中释放出来。

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

    现在,当 Rmd 被编织时,工作区中不再有 testtrainfit,而是在工作区中只有 r(和 myFun,这实际上是无成本的)

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

    更新

    RE:缓存 = TRUE

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

    回复:gc()

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

    re:外部资源

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

    【讨论】:

    • 这是个好主意 - 但我将不得不彻底改变我对编写代码的看法......
    • RStudio 的代码菜单中有一个“提取函数”命令,可以为您完成大部分繁重工作。
    • 我添加了一些关于您的一些子问题的更多讨论。
    猜你喜欢
    • 2015-04-26
    • 1970-01-01
    • 2016-10-12
    • 2013-03-28
    • 1970-01-01
    • 2021-01-23
    • 2013-01-17
    • 2011-02-18
    • 2011-07-01
    相关资源
    最近更新 更多