获得"节点堆栈溢出"当cbind多个稀疏矩阵时

时间:2016-06-02 01:51:07

标签: r sparse-matrix

我有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()粉碎的原因。

2 个答案:

答案 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大小,以确保它可以容纳大矩阵大小。