我有100,000个稀疏矩阵(" dgCMatrix")存储在列表对象中。每个矩阵的行号相同(8,000,000),列表的大小约为25 Gb。现在我做的时候:
do.call(cbind, theListofMatrices)
将所有矩阵组合成一个大的稀疏矩阵,我得到了#34;节点堆栈溢出"。实际上,我甚至不能用该列表中的500个元素来做这个,它应该输出一个大小只有100 Mb的稀疏矩阵。
我的猜测是 cbind()函数将稀疏矩阵转换为普通的密集矩阵,从而导致堆栈溢出?
实际上,我尝试过这样的事情:
tmp = do.call(cbind, theListofMatrices[1:400])
这很好用,tmp仍然是一个大小为95 Mb的稀疏矩阵,然后我尝试了:
> tmp = do.call(cbind, theListofMatrices[1:410])
Error in stopifnot(0 <= deparse.level, deparse.level <= 2) :
node stack overflow
然后发生错误。但是,我可以毫不费力地做一些事情:
cbind(tmp, tmp, tmp, tmp)
因此,我认为它与do.call()
有关Reduce()似乎解决了我的问题,虽然我还不知道do.call()粉碎的原因。
答案 0 :(得分:2)
问题不在do.call()
中,而是由于实现了Matrix包中cbind
的方式。它使用递归将各个参数绑定在一起。例如,Matrix::cbind(mat1, mat2, mat3)
被翻译为Matrix::cbind(mat1, Matrix::cbind(mat2, mat3))
行。
由于do.call(cbind, theListofMatrices)
基本上是cbind(theListofMatrices[[1]], theListofMatrices[[2]], ...)
,因此你对cbind
函数的参数太多了,你最终会得到一个嵌套太深的递归而且会失败。
因此,Ben's comment使用Reduce()
是解决该问题的好方法,因为它避免了递归并将其替换为迭代:
tmp <- Reduce(cbind, theListofMatrices[-1], theListofMatrices[[1]])
答案 1 :(得分:0)
在R中:2列矩阵最多可包含2 ^ 30-1行= 1073,741,823行。因此,我会检查行号并检查RAM大小,以确保它可以容纳大矩阵大小。