remplacer une liste de valeurs par une autre dans R

j'ai une dataframe avec n'importe laquelle de ces valeurs.

from=c("A","C","G","T","R","Y","M","K","W", "S","N")

et je veux remplacer en conséquence avec

to=c("AA","CC","GG","TT","AG","CT","AC","GT","AT", "CG","NN")

Quelle est la meilleure façon de faire cela , boucle toutes les valeurs à remplacer? ou boucle sur la position de la matrice. ou toute autre solution?

dd<-matrix(sample(from, 100, replace=TRUE), 10) 

dd
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,] "K"  "S"  "G"  "T"  "R"  "N"  "A"  "C"  "W"  "M"  
 [2,] "Y"  "K"  "S"  "G"  "T"  "R"  "N"  "A"  "C"  "W"  
 [3,] "M"  "Y"  "K"  "S"  "G"  "T"  "R"  "N"  "A"  "C"  
 [4,] "W"  "M"  "Y"  "K"  "S"  "G"  "T"  "R"  "N"  "A"  
 [5,] "C"  "W"  "M"  "Y"  "K"  "S"  "G"  "T"  "R"  "N"  
 [6,] "A"  "C"  "W"  "M"  "Y"  "K"  "S"  "G"  "T"  "R"  
 [7,] "N"  "A"  "C"  "W"  "M"  "Y"  "K"  "S"  "G"  "T"  
 [8,] "R"  "N"  "A"  "C"  "W"  "M"  "Y"  "K"  "S"  "G"  
 [9,] "T"  "R"  "N"  "A"  "C"  "W"  "M"  "Y"  "K"  "S"  
[10,] "G"  "T"  "R"  "N"  "A"  "C"  "W"  "M"  "Y"  "K"

j'ai utilisé une boucle sur tous de pour de.

myfunc<-function(xx){

  from=c("A","C","G","T","R","Y","M","K","W", "S","N");
  to=c("AA","CC","GG","TT","AG","CT","AC","GT","AT", "CG","NN");
  for (i in 1:11){
      xx[xx==from[i]]<-to[i];
  }
  return(xx);
}

cela a très bien fonctionné pour une petite matrice, mais cela prend beaucoup de temps pour une grande matrice. Une solution efficace?

Merci

18
r
demandé sur Roman Luštrik 2013-04-10 00:48:39

3 réponses

Créer une carte

map = setNames(to, from)

et passer de A à B

dd[] = map[dd]

La carte sert une look-up, associant 'de' noms 'de' valeurs. La tâche préserve les dimensions de la matrice et les noms dimnames.

24
répondu Martin Morgan 2013-04-09 21:08:41
matrix(to[match(dd,from)], nrow=nrow(dd))

match renvoie un vecteur sans dimensions, donc vous devez recréer la matrice.

5
répondu Theodore Lytras 2013-04-09 20:56:58

j'ai utilisé une boucle similaire à OP et chronométré les solutions. Celui de Theodore est le plus rapide, mais celui de Martin est très lisible.

dd<-matrix(sample(from, 100, replace = TRUE),10,10)
ddr <- dd
ddm <- dd
ddt <- dd

benchmark(roman = {
  for (i in 1:length(from)) {
    ddr[ddr == from[i]] <- to[i]
  }},
  martin = {
    map = setNames(to, from)
    ddm[] = map[dd]
  },
theodore = {ddt <- matrix(to[match(dd,from)], nrow=nrow(dd))},
          replications = 100000
)
      test replications elapsed relative user.self sys.self user.child sys.child
2   martin       100000    1.93    1.191      1.91        0         NA        NA
1    roman       100000    8.23    5.080      8.11        0         NA        NA
3 theodore       100000    1.62    1.000      1.61        0         NA        NA
3
répondu Roman Luštrik 2013-04-09 21:10:29