2012-05-14 19 views
5

Sto utilizzando operatori corrispondenti per acquisire i valori visualizzati in una matrice da un frame di dati separato. Tuttavia, la matrice risultante ha i valori nell'ordine in cui appaiono nel frame di dati, non nella matrice originale. C'è un modo per preservare l'ordine della matrice originale usando l'operatore corrispondente?R: conserva l'ordine quando si utilizzano gli operatori corrispondenti (% in%)

Ecco un breve esempio:

vec=c("b","a","c"); vec 

df=data.frame(row.names=letters[1:5],values=1:5); df 

df[rownames(df) %in% vec,1] 

Questo produce > [1] 1 2 3 che è l'ordine "a" "b" "c" appare nella cornice dati. Tuttavia, mi piacerebbe generare >[1] 2 1 3 che è l'ordine in cui appaiono nel vettore originale.

Grazie!

risposta

6

Usa match.

df[match(vec, rownames(df)), ] 
# [1] 2 1 3 

essere consapevoli che se si dispone di valori duplicati in entrambi i vec o rownames(df), match potrebbe non funzionare come previsto.

Edit: Ho appena realizzato che il nome di fila indicizzazione risolverà il problema un po 'più semplice ed elegante:

df[vec, ] 
# [1] 2 1 3 
+0

per l'utilizzo dell'indicizzazione dei nomi delle righe, ma entrambe le soluzioni funzionano. Grazie! – jslefche

3

Usa match (e sbarazzarsi della NA valori per gli elementi in formato vettoriale per coloro che non corrispondono nell'altro):

Filter(function(x) !is.na(x), match(rownames(df), vec)) 
+1

in realtà, se si combina con nomatch = 0, la corrispondenza restituirà 0 invece di NA per gli elementi che non corrispondono. Poiché la selezione di riga di [] ignora solo 0, puoi semplicemente inserire la directory dei risultati della corrispondenza in [], rimuovendo la necessità di filtrare i punti bonus – frankc

0

Dal nome della riga indicizzazione funziona anche su vettori, possiamo prendere questo un ulteriore passo avanti e definire:

'%ino%' <- function(x, table) { 
    xSeq <- seq(along = x) 
    names(xSeq) <- x 
    Out <- xSeq[as.character(table)] 
    Out[!is.na(Out)] 
} 

ora abbiamo il risultato desiderato:

df[rownames(df) %ino% vec, 1] 
[1] 2 1 3 

All'interno della funzione, i nomi() fa un auto convertire in carattere e tabella viene modificata con as.character(), quindi questo funziona anche correttamente quando gli ingressi al% ino% sono i numeri:

LETTERS[1:26 %in% 4:1] 
[1] "A" "B" "C" "D" 


LETTERS[1:26 %ino% 4:1] 
[1] "D" "C" "B" "A" 

seguito % in%, valori mancanti vengono rimossi:

LETTERS[1:26 %in% 3:-5] 
[1] "A" "B" "C" 

LETTERS[1:26 %ino% 3:-5] 
[1] "C" "B" "A" 

con% in% sequenza logica viene ripetuta lungo la dimensione dell'oggetto da subsetted, questo non è il caso con% ino%:

data.frame(letters, LETTERS)[1:5 %in% 3:-5,] 

    letters LETTERS 
1  a  A 
2  b  B 
3  c  C 
6  f  F 
7  g  G 
8  h  H 
11  k  K 
12  l  L 
13  m  M 
16  p  P 
17  q  Q 
18  r  R 
21  u  U 
22  v  V 
23  w  W 
26  z  Z 


data.frame(letters, LETTERS)[1:5 %ino% 3:-5,] 

    letters LETTERS 
3  c  C 
2  b  B 
1  a  A 
Problemi correlati