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
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.
matrix(to[match(dd,from)], nrow=nrow(dd))
match
renvoie un vecteur sans dimensions, donc vous devez recréer la matrice.
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