2013-04-09 11 views
17

Mam ramkę danych z dowolną z tych wartości.zamień listę wartości na inną w R

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

i chcę odpowiednio zastąpić

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

co jest najlepszym sposobem na to, pętla nad wszystkimi wartościami zastąpić? lub pętla nad położeniem matrycy. lub jakiekolwiek inne rozwiązanie?

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" 

Użyłem pętli dla wszystkich od do do.

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

to działało świetnie na małej matrycy, ale zajmuje dużo czasu na dużą matrycę. Jakieś skuteczne rozwiązanie?

Dzięki

+2

+1 za powtarzalny przykład, jasne pytanie i pokazany wysiłek. –

Odpowiedz

22

utworzyć mapę

map = setNames(to, from) 

i przejść z punktu A do punktu B

dd[] = map[dd] 

Mapa służy jako look-up, obcowania 'z' nazwy z 'do' wartości. Przypisanie zachowuje wymiary i nazwy wymiarów macierzy.

+0

Dobra sztuczka! ('map') –

+0

Dziękuję, ale mam błąd' >> map = setNames (to, from) > ll2 [] <- map [ll] Błąd na mapie [ll]: niepoprawny indeks typu "lista" ' – Ananta

+1

@Ananta Myślę, że' ll' to data.frame, a nie matryca, tak różna od twojego pytania. Możesz "ll [] = map [as.matrix (ll)]". Również nie jest jasne, czym jest "ll2"; może chcesz ponownie odwiedzić swoje pytanie? Uważaj, ponieważ kolumny ramek danych mogą być również czynnikami. –

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

zwraca wektor bez wymiarów, więc musisz odtworzyć macierz.

+0

Dziękuję Theodore – Ananta

3

Użyłem podobnej pętli jak OP i ustaliłem czas rozwiązania. Theodore jest najszybszy z niewielkim marginesem, ale Martin jest bardzo czytelny.

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 
Powiązane problemy