2013-04-09 15 views
17

Ich habe ein Datenframe mit einem dieser Werte.ersetzen Sie eine Liste von Werten durch eine andere in R

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

und ich möchte mit

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

entsprechend ersetzen Was ist der beste Weg, das zu tun, Schleife über alle Werte zu ersetzen? oder Schleife über die Matrixposition. oder irgendeine andere Lösung?

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" 

Ich verwendete Schleife über alle von zu zu.

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); 
} 

es funktionierte gut für kleine Matrix, aber dauert eine lange Zeit für große Matrix. Jede effiziente Lösung?

Dank

+2

+1 für reproduzierbare Beispiel, klare Frage und Aufwand gezeigt. –

Antwort

22

A und von A gehen

map = setNames(to, from) 

Karte erstellen

dd[] = map[dd] 

Die Karte dient als Look-up nach B 'von' Namen, die mit 'zu' Zuordnen Werte. Die Zuweisung behält Matrixdimensionen und Dimnamen bei.

+0

Netter Trick! (die 'map') –

+0

Danke, aber ich habe einen Fehler '>> map = setNames (zu, von) > ll2 [] <- map [ll] Fehler in map [ll]: ungültiger tiefgestellter Typ' list ' ' – Ananta

+1

@Ananta Ich denke,' ll' ist ein data.frame, nicht Matrix, so anders als Ihre Frage. Sie könnten [] = map [as.matrix (ll)] '. Auch nicht klar, was 'll2' ist; Vielleicht möchtest du deine Frage erneut besuchen? Seien Sie vorsichtig, da Datenrahmenspalten durchaus Faktoren sein können. –

5
matrix(to[match(dd,from)], nrow=nrow(dd)) 

match liefert einen Vektor ohne Dimensionen, so müssen Sie die Matrix neu erstellen.

+0

Danke Theodore – Ananta

3

Ich verwendete eine ähnliche Schleife als OP und zeitlich abgestimmt die Lösungen. Theodore's ist mit einem kleinen Vorsprung am schnellsten, aber Martins ist sehr gut lesbar.

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 
Verwandte Themen