RMarkdown、R 笔记本和内存管理
RMarkdown, R Notebooks, and Memory Management
我正在从事一个涉及分析几个非常大的文本文件的项目。我已将项目分成几个部分,每个部分都将在自己的 RMarkdown/R Notebook 中完成,但我 运行 正在解决实际问题。
首先,当我处理一部分(一个 R 文件)时,我必须定期 rm
变量并使用 gc()
重新捕获内存。当我准备好编织文件时,我认为 R 将重新 运行 一切——这意味着我需要用我的 rm/gc 步骤明确地写入块。这个对吗?我知道您可以将选项 cache = TRUE
放在块选项中,但我以前没有这样做过。如果我这样做,是否所有这些结果都保存在内存中(即缓存中)?如果是这样,当我删除变量并重新捕获内存时会发生什么?这是无需重新运行 一切即可保存用于演示的结果的正确方法吗?
谢谢!
您的问题是您的代码将所有内容转储到全局环境(您的 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))
}
现在,您的工作区中只有 r
(并且myFun
,几乎没有成本)
奖励:您会发现,您的分析时间越长,您就可以重用这些函数!
更新
回复:缓存 = 真
回答你后面的问题。 cache=TRUE
将从 RDS
文件加载,而不是重新 运行 代码块。作为一种最小化内存使用的工具,它可能是有效的——但您仍然需要记住在数据从缓存加载时从工作区中删除数据,而不是 运行ning。您应该将此视为节省时间,而不是节省内存,除非您手动清理。
回复:gc()
gc
或“垃圾收集”是一个进程的触发器,R 运行 经常自行收集和转储它暂时持有但不再使用的内存。 R 中的垃圾收集非常好,但使用 gc
可以帮助在更顽固的情况下释放内存。 Hadley 在这里做了很好的总结:http://adv-r.had.co.nz/memory.html。话虽如此,它很少成为灵丹妙药,通常情况下,如果您觉得需要使用它,您要么需要重新考虑您的方法,要么需要重新考虑您的硬件,或者两者兼而有之。
回复:外部资源
这听起来有点轻率,但有时加载另一台比您的机器大得多的机器来完成工作比修复内存泄漏要便宜得多(时间 == $)。示例:具有 16 个内核和 128GB RAM 的 R5 每小时 1 美元。对你时间的微积分往往是相当有利可图的。
我正在从事一个涉及分析几个非常大的文本文件的项目。我已将项目分成几个部分,每个部分都将在自己的 RMarkdown/R Notebook 中完成,但我 运行 正在解决实际问题。
首先,当我处理一部分(一个 R 文件)时,我必须定期 rm
变量并使用 gc()
重新捕获内存。当我准备好编织文件时,我认为 R 将重新 运行 一切——这意味着我需要用我的 rm/gc 步骤明确地写入块。这个对吗?我知道您可以将选项 cache = TRUE
放在块选项中,但我以前没有这样做过。如果我这样做,是否所有这些结果都保存在内存中(即缓存中)?如果是这样,当我删除变量并重新捕获内存时会发生什么?这是无需重新运行 一切即可保存用于演示的结果的正确方法吗?
谢谢!
您的问题是您的代码将所有内容转储到全局环境(您的 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))
}
现在,您的工作区中只有 r
(并且myFun
,几乎没有成本)
奖励:您会发现,您的分析时间越长,您就可以重用这些函数!
更新
回复:缓存 = 真
回答你后面的问题。 cache=TRUE
将从 RDS
文件加载,而不是重新 运行 代码块。作为一种最小化内存使用的工具,它可能是有效的——但您仍然需要记住在数据从缓存加载时从工作区中删除数据,而不是 运行ning。您应该将此视为节省时间,而不是节省内存,除非您手动清理。
回复:gc()
gc
或“垃圾收集”是一个进程的触发器,R 运行 经常自行收集和转储它暂时持有但不再使用的内存。 R 中的垃圾收集非常好,但使用 gc
可以帮助在更顽固的情况下释放内存。 Hadley 在这里做了很好的总结:http://adv-r.had.co.nz/memory.html。话虽如此,它很少成为灵丹妙药,通常情况下,如果您觉得需要使用它,您要么需要重新考虑您的方法,要么需要重新考虑您的硬件,或者两者兼而有之。
回复:外部资源
这听起来有点轻率,但有时加载另一台比您的机器大得多的机器来完成工作比修复内存泄漏要便宜得多(时间 == $)。示例:具有 16 个内核和 128GB RAM 的 R5 每小时 1 美元。对你时间的微积分往往是相当有利可图的。