【问题标题】:How to handle for loop with large objects in Rstudio?如何在 Rstudio 中处理带有大对象的 for 循环?
【发布时间】:2020-06-06 20:54:01
【问题描述】:

我有一个包含大对象的 for 循环。根据我的反复试验,我只能加载一次大对象。如果我再次加载对象,将返回错误“错误:无法分配大小为 *** Mb 的向量”。我试图通过在 for 循环结束时删除对象来克服这个问题。但是,在 for 循环的第二次运行开始时,我仍然返回错误“错误:无法分配大小为 699.2 Mb 的向量”。

我的 for 循环结构如下:

for (i in 1:22) {
  VeryLargeObject <- ...i... 
  ...
  .
   .
    .
  ...
  rm(VeryLargeOjbect)
}

VeryLargeObjects 的范围为 2-3GB。我的电脑有 16Gb 的 RAM,8 核,64 位 Win10。

关于如何完成 for 循环的任何解决方案?

【问题讨论】:

  • 你检查或指定环境了吗?

标签: for-loop matrix vector memory-management


【解决方案1】:

错误“无法分配...”可能来自 rm() 不会立即释放内存。因此,当您加载第二个对象时,第一个对象仍然占用 RAM。未分配给任何名称(变量)的对象将在 R 自行决定的时间点由 R 收集垃圾。

大多数补救措施来自不将整个对象加载到 RAM 中:

  • 如果您正在使用矩阵,请使用 bigmemory 包创建 filebacked.big.matrix()。使用var[...,...] 语法将您的数据写入此对象,就像普通矩阵一样。然后,在一个新的 R 会话(以及一个新的 R 脚本以保持可重复性)中,您可以从磁盘加载此矩阵并对其进行修改。

  • mmap 包使用类似的方法,利用操作系统将 RAM 页面映射到磁盘的能力。所以它们在程序中看起来就像在 ram 中一样,但是是从磁盘读取的。为了提高速度,操作系统负责将相关部分保存在 RAM 中。

  • 如果您使用数据框,您可以使用 fstfeather 之类的包,它们使您能够仅将部分数据框加载到变量中。

  • 将您的数据框传输到 sqlite 之类的数据库中,然后使用 R 访问该数据库。dbplyr 包使您可以将数据库视为 tidyverse 样式的数据集。这是RStudio help page。你也可以使用raw SQL commands with the package DBI

另一种方法是不以交互方式编写,而是编写一个只处理一个对象的 R 脚本:

编写一个名为 processBigObject.R 的 R 脚本,使用 commandArgs() 从命令行获取大对象的文件名:

#!/usr/bin/env Rscript
#
# Process a big object
# 
# Usage: Rscript processBigObject.R <FILENAME>

input_filename <- commandArgs(trailing = TRUE)[1]
output_filename <- commandArgs(trailing = TRUE)[2]

# I'm making up function names here, do what you must for your object
o <- readBigObject(input_filename) 
s <- calculateSmallerSummaryOf(o)

writeOutput(s, output_filename)

然后,编写一个shell脚本或使用system2()多次调用该脚本,使用不同的文件名。因为 R 在每个对象之后终止,所以内存被释放:

system2("Rscript", c("processBigObject.R", "bigObject1.dat", "bigObject1_result.dat"))
system2("Rscript", c("processBigObject.R", "bigObject2.dat", "bigObject2_result.dat"))
system2("Rscript", c("processBigObject.R", "bigObject3.dat", "bigObject3_result.dat"))
...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-03
    • 1970-01-01
    • 1970-01-01
    • 2017-11-24
    • 2021-07-26
    • 1970-01-01
    • 2020-05-31
    • 2016-11-18
    相关资源
    最近更新 更多