2012-05-14 20 views
5

Estoy usando operadores coincidentes para tomar valores que aparecen en una matriz desde un marco de datos separado. Sin embargo, la matriz resultante tiene los valores en el orden en que aparecen en el marco de datos, no en la matriz original. ¿Hay alguna manera de preservar el orden de la matriz original usando el operador de coincidencia?R - conservar el orden cuando se utilizan operadores coincidentes (% en%)

Aquí está un ejemplo rápido:

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

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

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

Esto produce > [1] 1 2 3 que es el orden "a" "b" "c" aparece en la trama de datos. Sin embargo, me gustaría generar >[1] 2 1 3 que es el orden en que aparecen en el vector original.

Gracias!

Respuesta

6

Uso match.

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

Tenga en cuenta que si tiene valores duplicados en cualquiera vec o rownames(df), match no se pueden comportar como se espera.

Editar: me di cuenta de que nombre de la fila de indexación va a resolver su problema un poco más sencilla y elegante:

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

puntos de bonificación por utilizar la indexación de nombres de fila, pero ambas soluciones funcionan. ¡Gracias! – jslefche

3

Uso match (y deshacerse de la AN valores de los elementos, ya sea en el vector para los que no coinciden en el otro):

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

En realidad, si coincide con nomatch = 0, Match devolverá 0 en lugar de NA para los elementos que no coinciden. Como la selección de fila de [] solo ignora los 0, puede colocar el directorio de resultados de los partidos en [], eliminando la necesidad de filtrar – frankc

0

Desde nombre de la fila de indexación también trabaja en vectores, podemos llevar esto un paso más allá y definir:

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

ahora tenemos el resultado deseado:

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

Dentro de la función, nombres() tiene un auto convertir al carácter y la tabla se cambia con as.character(), así que esto también funciona correctamente cuando las entradas a% ino% son números:

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


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

Siguiendo % en%, valores que faltan se eliminan:

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

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

con% en% la secuencia lógica se repite a lo largo de la dimensión del objeto que se subjuegos, este no es el 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 
Cuestiones relacionadas