在我当前的项目中,我有一个计算函数,它在向量A的一个元素上运行,并返回一个列表元素,我将其插入到列表B中。返回元素包含许多与第一个列表相关的大型任意大小的矩阵
作为一个例子,让我们采用一个原始数字为n的函数,并生成一个n x n的随机矩阵。
vector.A <- sample(1:2000, 15000, replace = TRUE)
list.B <- as.list(rep(NA, length(vector.A)))
arbitraryMatrix <- function(n) {
matrix(rnorm(n*n), ncol = n, nrow = n)
}
for ( i in which(is.na(list.B)) ) {
print(i)
list.B[[i]] <- arbitraryMatrix( vector.A[i] )
}
这个函数减慢了较大的list.B得到(实际上我很确定它会在R完成循环之前崩溃)。在我看来,list.B的任何元素在创建之后都不会被再次访问,因此可以将其写入磁盘而不是以减慢计算速度的方式占用内存。
我可以编写一个脚本,通过将块保存到.rda文件来实现这一目的,但我希望有人有一个更优雅的解决方案。
FF包看起来像是一个有趣的可能性 http://cran.r-project.org/web/packages/ff/ff.pdf 但据我所知,它不支持列表对象。
注意事项:
答案 0 :(得分:2)
以下是使用filehash包的答案。这是一个很好的方法,因为它具有令人印象深刻的微小内存占用,随着功能的进展几乎没有增加。这样就实现了你的目标之一。
然而,这是一个糟糕的方法,因为它有两个实质性的缺点...(1)它非常慢,如果你打开一个进程监视器,你可以看到磁盘和内存交换正在进行一个相当悠闲的速度(在我的机器上,至少)。实际上它太慢了我不确定它是否随着它的进一步变慢而变慢。我没有运行它完成,只是在我在内存中运行函数时遇到错误的地方(约350项左右)说服自己它比在内存中运行更好(此时磁盘对象是73 GB)。这是第二个缺点,创建的磁盘对象是大量。
所以这里希望其他人能够更好地回答你的问题(也许是mmap
?),我最感兴趣的是。
# set up disk storage object
library(filehash)
dbCreate("myTestDB")
db <- dbInit("myTestDB")
# put data on disk
db$A <- sample(1:2000, 15000, replace = TRUE)
db$B <- as.list(rep(NA, length(db$A)))
# function
arbitraryMatrix <- function(n) {
matrix(rnorm(n*n), ncol = n, nrow = n)
}
# run function by accessing disk objects
for ( i in which(is.na(db$B)) ) {
print(i)
db$B[[i]] <- arbitraryMatrix( db$A[i] )
}
# run function by accessing disk objects, following
# Jon's comment to treat db as a list
for ( i in which(is.na(db$B)) ) {
print(i)
db[[as.character(i)]] <- arbitraryMatrix( db$A[i] )
}
# use db[[as.character(1)]] etc to access the list items