Erzeugen eine sehr große Matrix von String-Kombinationen mit combn () und BigMemory Paket

StackOverflow https://stackoverflow.com/questions/4493287

  •  12-10-2019
  •  | 
  •  

Frage

Ich habe einen Vektor x von 1.344 einzigartigen Saiten. Ich möchte eine Matrix erzeugen, die mir alle möglichen Gruppen von drei Werten gibt, unabhängig von der Reihenfolge und dem Export, die zu einer csv.

Ich bin mit R auf EC2 auf einer m1.large Instanz w 64-Bit-Ubuntu. Wenn combn mit (x, 3) Ich nicht genügend Arbeitsspeicher Fehlermeldung erhalten:

Error: cannot allocate vector of size 9.0 Gb

Die Größe der resultierenden Matrix ist C1344,3 = 403.716.544 Zeilen und drei Spalten -., Die die Transponierte des Ergebnisses der combn () Funktion

Ich dachte an das BigMemory Paket mit einer Datei erstellen gesichert big.matrix so dass ich dann die Ergebnisse der combn () Funktion zuweisen kann. Ich kann eine vorbelegt große Matrix erstellen:

library(bigmemory)
x <- as.character(1:1344)
combos <- 403716544
test <- filebacked.big.matrix(nrow = combos, ncol = 3, 
        init = 0, backingfile = "test.matrix")

Aber wenn ich versuche, die Werte zuweisen test <- combn(x, 3) ich immer noch das gleiche bekommen: Error: cannot allocate vector of size 9.0 Gb

Ich habe sogar versucht, das Ergebnis der combn(x,3) Nötigung aber ich denke, dass, weil die combn () Funktion einen Fehler zurückgibt, die big.matrix Funktion funktioniert auch nicht.

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'

Gibt es eine Möglichkeit, diese beiden Funktionen zu kombinieren zusammen zu bekommen, was ich brauche? Gibt es andere Möglichkeiten, um dies zu erreichen? Danke.

War es hilfreich?

Lösung

Sie können zunächst alle 2-Wege-Kombinationen finden, und sie dann nur mit dem 3D-Wert kombinieren, während sich jedes Mal zu sparen. Dies nimmt viel weniger Speicher:

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")

Das ist nicht so allgemein wie Joshua Antwort obwohl es speziell für Ihren Fall ist. Ich denke, es ist schneller-wieder, für diesen besonderen Fall-, aber ich habe nicht den Vergleich. Funktion funktioniert auf meinem Computer etwas mehr als 50 Mb mit (grob geschätzt), wenn auf Ihren x angewandt.

EDIT

Auf Nebenbei bemerkt: Wenn diese für die Simulation ist, finde ich es schwer zu glauben, dass jede wissenschaftliche Anwendung benötigt mehr als 400 Millionen Simulationsläufe. Man könnte hier die richtige Antwort auf die falsche Frage stellen ...

Proof of Concept:

änderte ich die Schreibleitung durch tt[[i]]<-out, hinzugefügt tt <- list() vor der Schleife und zurück (tt) nach. Dann gilt:

> 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" 
scroll top