使用R ff写大矩阵

时间:2013-05-28 15:59:36

标签: r matrix

过去几天我一直在发布有关我需要创建7000x7000距离矩阵的问题。在内存上做这一切是给我无法分配矢量错误。我使用的是Windows XP SP 3,3GB RAM,32位系统。我原本想使用bigmemory库,但似乎它不适用于Windows。我已经对ff package做了一些阅读,所以这就是我到目前为止所提到的:

require(ff)    
ffmat <- ff(vmode="double", dim=c(7000,7000))
ffmat <- as.matrix(dist(data[1:7000, ], diag=TRUE, upper=TRUE))

问题是我仍然遇到矢量分配错误。请注意dim(data) = 7000x182(很多变量)。

运行gc()验尸后会将memory.size()恢复到正常水平。就像R在写入创建的ff之前将结果存储在内存中一样。有没有办法解决?

3 个答案:

答案 0 :(得分:0)

您可能需要将任务分解为多个部分并将各个部分分配到矩阵中,而不是一步完成。

distas.matrix函数不知道结果将是ff对象,它们只是试图在内存中发挥作用。

由于dist函数不计算不同数据集之间的距离,因此最简单的方法就是手动计算距离,尽管包中可能有一个函数可以执行非对角线距离。

答案 1 :(得分:0)

  

“就好像R在写入创建的ff之前将结果存储在内存中。有没有办法解决这个问题?”

这正是R正在做的事情。编写代码的方式有两个:它创建一个ff对象,然后用as.matrix创建的传统矩阵覆盖它。

您可以扩展dist函数以使用ff个对象,或编写自己使用dist的{​​{1}}实现。

答案 2 :(得分:0)

非常感谢jwijffels指导我朝着正确的方向前进,并感谢http://rmazing.wordpress.com/2013/02/22/bigcor-large-correlation-matrices-in-r/从正确的方向开始。

假设一个名为training.data的7000x180数据矩阵。目标是创建尺寸为7000x7000的对称距离矩阵。实际上,使用daisy()创建了一个不相似度量,但它的逻辑相似。

distff <- function(training.data, nblocks=5, verbose=TRUE) {
  require(ff)
  require(cluster)
  ffmat <- ff(vmode="single", dim=c(7000,7000), filename="if so desired")
  nro <- nrow(training.data)
  ### This could be changed to handle rowcounts that have 
  ### modulus(nro/nblocks) != 0
  splt <- split(1:nro, rep(1:nblocks, each = nro/nblocks))
  COMBS <- expand.grid(1:length(splt), 1:length(splt)) 
  COMBS <- t(apply(COMBS, 1, sort)) 
  COMBS <- unique(COMBS) 
  for (i in 1:nrow(COMBS)) {
    COMB <- COMBS[i,]
    ### Since g1 and g2 get appended below, it wouldn't make sense to append the
    ### same group to itself
    if (COMB[1] != COMB[2]) {
      g1 <- splt[[COMB[1]]]
      g2 <- splt[[COMB[2]]]
      slj <- as.matrix(daisy(training.data[c(g1,g2),], metric="gower", 
                             stand=FALSE))
      ffmat[c(g1,g2), c(g1,g2)] <- slj
      rm(slj)
      gc()
    }
  }
}

就是这样。我意识到存在一些效率低下的问题(比如多次写几个组)。我很好,因为它有效。就像我说的那样,大部分代码都是从上面引用的网站上借鉴和定制的。