我有1,344个唯一字符串的向量x。我想生成一个矩阵,该矩阵为我提供三个值的所有可能的组,而与顺序无关,并将其导出到csv。

我在带有64位Ubuntu的m1.large实例上的EC2上运行R。当使用combn(x,3)时,出现内存不足错误:

Error: cannot allocate vector of size 9.0 Gb

所得矩阵的大小为C1344,3 = 403,716,544行和三列-这是combn()函数的结果的转置。

我想到了使用bigmemory包创建一个由文件big.matrix支持的文件,以便随后可以分配combn()函数的结果。我可以创建一个预分配的大矩阵:
library(bigmemory)
x <- as.character(1:1344)
combos <- 403716544
test <- filebacked.big.matrix(nrow = combos, ncol = 3,
        init = 0, backingfile = "test.matrix")

但是当我尝试分配值test <- combn(x, 3)时,我仍然得到相同的信息:Error: cannot allocate vector of size 9.0 Gb
我什至尝试强制combn(x,3)的结果,但我认为由于combn()函数返回错误,因此big.matrix函数也不起作用。
test <- as.big.matrix(matrix(combn(x, 3)), backingfile = "abc")
Error: cannot allocate vector of size 9.0 Gb
Error in as.big.matrix(matrix(combn(x, 3)), backingfile = "abc") :
  error in evaluating the argument 'x' in selecting a method for function 'as.big.matrix'

有没有一种方法可以将这两个功能结合在一起以获得我所需要的东西?还有其他方法可以实现这一目标吗?谢谢。

最佳答案

您可以首先找到所有2向组合,然后将它们与3d值组合在一起,同时每次保存它们。这会占用更少的内存:

combn.mod <- function(x,fname){
  tmp <- combn(x,2,simplify=F)
  n <- length(x)
  for ( i in x[-c(n,n-1)]){
    # Drop all combinations that contain value i
    id <- which(!unlist(lapply(tmp,function(t) i %in% t)))
    tmp <- tmp[id]
    # add i to all other combinations and write to file
    out <- do.call(rbind,lapply(tmp,c,i))
    write(t(out),file=fname,ncolumns=3,append=T,sep=",")
  }
}

combn.mod(x,"F:/Tmp/Test.txt")

但是,这不像约书亚的回答那么笼统,它专门针对您的情况。我想它还是更快-再次针对此特定情况-但我没有进行比较。应用于x时,该功能在我的计算机上仅使用略高于50 Mb的带宽(大致估算)即可工作。

编辑

旁注:如果这是出于仿真目的,我很难相信任何科学应用程序都需要进行400+百万次仿真。您可能在这里对错误的问题提出了正确的答案...

概念证明:

我通过tt[[i]]<-out更改了写行,在循环之前添加了tt <- list(),并在循环之后添加了return(tt)。然后:
> do.call(rbind,combn.mod(letters[1:5]))
      [,1] [,2] [,3]
 [1,] "b"  "c"  "a"
 [2,] "b"  "d"  "a"
 [3,] "b"  "e"  "a"
 [4,] "c"  "d"  "a"
 [5,] "c"  "e"  "a"
 [6,] "d"  "e"  "a"
 [7,] "c"  "d"  "b"
 [8,] "c"  "e"  "b"
 [9,] "d"  "e"  "b"
[10,] "d"  "e"  "c"

关于r - 使用combn()和bigmemory包生成非常大的字符串组合矩阵,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4493287/

10-11 04:22