Génération d'une matrice très grand nombre de combinaisons de chaînes en utilisant Combn () et package BigMemory

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

  •  12-10-2019
  •  | 
  •  

Question

J'ai un vecteur x de 1.344 chaînes uniques. Je veux générer une matrice qui me donne tous les groupes possibles de trois valeurs, quel que soit l'ordre, et à l'exportation qu'à un csv.

Je suis en cours d'exécution R sur EC2 sur une instance de m1.large avec Ubuntu 64 bits. Lorsque vous utilisez Combn (x, 3) Je reçois une erreur de dépassement de mémoire:

Error: cannot allocate vector of size 9.0 Gb

La taille de la matrice résultante est C1344,3 = 403,716,544 lignes et trois colonnes. - qui est la transposée du résultat de la fonction Combn ()

Je pensais que d'utiliser le package BigMemory pour créer un fichier sauvegardé big.matrix afin que je puisse ensuite affecter les résultats de la fonction Combn (). Je peux créer une grande matrice préalloué:

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

Mais quand je tente d'affecter les valeurs test <- combn(x, 3) je reçois toujours la même: Error: cannot allocate vector of size 9.0 Gb

J'ai même essayé de contraindre le résultat de combn(x,3) mais je pense que parce que la fonction Combn () retourne une erreur, la fonction big.matrix ne fonctionne pas non plus.

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'

Est-il possible de combiner ces deux fonctions ensemble pour obtenir ce que je besoin? Y at-il d'autres moyens d'y parvenir? Merci.

Était-ce utile?

La solution

Vous pourriez d'abord trouver toutes les combinaisons 2 voies, puis il suffit de les combiner avec la valeur 3D tout en économisant chaque fois. Cela prend beaucoup moins de mémoire:

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

Ce n'est pas aussi général que la réponse de Joshua cependant, il est spécifiquement pour votre cas. Je suppose qu'il est plus rapide -Encore une fois, pour ce Case- particulier, mais je ne l'ai pas la comparaison. Fonction fonctionne sur mon ordinateur en utilisant peu plus de 50 Mb (estimation préliminaire) lorsqu'elle est appliquée à votre x.

EDIT

Sur un Sidenote: Si cela est à des fins de simulation, je trouve qu'il est difficile de croire que toute application scientifique a besoin 400+ millions pistes de simulation. Vous demandez peut-être la bonne réponse à la mauvaise question ici ...

preuve de concept:

J'ai changé la ligne d'écriture par tt[[i]]<-out, tt <- list() ajouté avant la boucle et retour (tt) après. Puis:

> 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