我正在用R构建基于代理的模型,但是尝试使用大对象却遇到了内存问题。特别是,在初始化时间创建了8个3D阵列,并且在每个时间步长,每个3D阵列都由不同的功能填充。
目前,反导系统运行了1825天,模拟了2500个人在整个地形上移动。风景中有1000个单元格。使用此配置,我不会出现内存问题。
在初始化时,
1个3D阵列就像:
h <- array(NA, dim=c(1825, 48, 2500),
dimnames=list(NULL, NULL, as.character(seq(1, 2500, 1))))
## 3th dimension = individual ID
1个3D阵列就像:
p <- array(NA, dim=c(1825, 38, 1000),
dimnames=list(NULL, NULL, as.character(seq(1, 1000, 1))))
## 3th dimension = cell ID
6个3D阵列如下:
t <- array(NA, dim=c(1825, 41, 2500),
dimnames=list(NULL, NULL, as.character(seq(1, 2500, 1))))
## 3th dimension = individual ID
数组包含数字和字符/字符串数据类型。
理想情况下,我想增加个人数量和/或补丁数量,但是由于内存问题,这是不可能的。似乎有一些可用的工具,例如bigmemory
,gc
来管理内存。这些工具有效吗?我是编程的新手,没有管理内存和高性能计算的经验。任何建议都将不胜感激,谢谢您的宝贵时间。
答案 0 :(得分:4)
据我了解,bigmemory
仅适用于矩阵,而不适用于多维数组,但是您可以将多维数组另存为矩阵列表。
gc
只是垃圾收集器,您不必真正调用它,因为它将被自动调用,但是手册中也指出:
删除大型对象后调用gc可能很有用,因为 这可能会提示R将内存返回给操作系统。
我认为对您来说最有用的软件包是ff
。
这是一个简短的示例,用于说明软件包ff
的强度,该软件包将数据存储在磁盘上,并且几乎不影响内存。
具有base-R的初始化数组:
p <- array(NA, dim=c(1825, 38, 1000),
dimnames=list(NULL, NULL, as.character(seq(1, 1000, 1))))
format(object.size(p), units="Mb")
“ 264.6 Mb”
因此,总体而言,您的初始阵列将已占用多达5GB的内存,这将使您在繁重的计算中遇到麻烦。
带有ff的初始化数组:
library(ff)
myArr <- ff(NA, dim=c(1825, 38, 1000),
dimnames=list(NULL, NULL, as.character(seq(1, 1000, 1))),
filename="arr.ffd", vmode="logical", overwrite = T)
format(object.size(myArr), units="Mb")
[1]“ 0.1 Mb”
平等性测试:
euqals <- list()
for (i in 1:dim(p)[1]) {
euqals[[i]] <- all.equal(p[i,,],
myArr[i,,])
}
all(unlist(euqals))
[1]是
答案 1 :(得分:3)
您是否必须坚持使用数组数据类型?
如果阵列中存在许多NA,则意味着您使用的内存超出了实际需要。这是R中数组的缺点。
如果您执行的操作不一定要求您的数据为数组,则应通过将其重构为data.frame来节省一些内存。
下面的示例显示您的数据状态。从数组转换后,frame看起来像。请注意,我必须显式使用na.rm=FALSE
,否则结果将是0行数据。
devtools::install_github("Rdatatable/data.table@as.dt.array.null.dimnames")
library(data.table)
p <- array(NA, dim=c(1825, 38, 1000),
dimnames=list(NULL, NULL, as.character(seq(1, 1000, 1))))
as.data.table(p, na.rm=FALSE)
# V1 V2 V3 value
# <int> <int> <char> <lgcl>
# 1: 1 1 1 NA
# 2: 1 1 10 NA
# 3: 1 1 100 NA
# 4: 1 1 1000 NA
# 5: 1 1 101 NA
另一种方法是使用data.cube包。它基本上会在后台为您完成我上面写的内容。您仍然拥有数组的[
运算符,但是data.cube对象不能与期望在输入上使用数组的R函数一起使用,因为它们会强制data.cube到数组失去所有内存的好处。
存储器的好处可能非常重要,例如data.cube vignette:
array: 34.13 GB
data.cube: 0.01 GB