Erzeugen eine sehr große Matrix von String-Kombinationen mit combn () und BigMemory Paket
-
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.
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"
Andere Tipps
Hier ist eine Funktion, die ich in R geschrieben habe, die zur Zeit ihrer (unexported) zu Hause in der
In erster Näherung alle Algorithmus Trades off Speicher für Geschwindigkeit. Sie haben eine Grenze treffen versuchen, Ihre voll aufgezählt Kombinationsmatrix vorzubelegen. Vielleicht sollten Sie nicht versuchen, diese Matrix zu vorzubelegen sondern versuchen, sagen wir, Wenn Sie glauben, die Kombinationen benötigen, berechnen sie woanders und speichern sie in einer einfachen db (oder, Heck, Flatfile) und suchen sie nach oben - 9 gb gespeichert Nutzen Sie den Vorteil von Open Source, lesen Sie den Code
combn()
und ändern Sie es in einen Client-Server Dingen: ein Anruf mit der Indexnummer angegeben N es, wird Schleife und gibt den Nth Eintrag. Nicht effizient, aber möglicherweise leichter möglich .