2009-10-14 15 views
79

Tengo un vector x, que me gustaría ordenar en función del orden de los valores en el vector y. Los dos vectores no son de la misma longitud.Cómo ordeno un vector según los valores de otro

x <- c(2, 2, 3, 4, 1, 4, 4, 3, 3) 
y <- c(4, 2, 1, 3) 

El resultado esperado sería:

[1] 4 4 4 2 2 1 3 3 3 

Respuesta

59

Aquí es un chiste ...

y[sort(order(y)[x])] 

[editar:] Esto se desglosa de la siguiente manera:

order(y)    #We want to sort by y, so order() gives us the sorting order 
order(y)[x]   #looks up the sorting order for each x 
sort(order(y)[x]) #sorts by that order 
y[sort(order(y)[x])] #converts orders back to numbers from orders 
+0

Eso es muy breve, pero estoy teniendo dificultades para descubrir qué está pasando allí. Podrías elaborar un poco? –

+0

Gracias! el orden() me desconcertaba, parecía estar reorganizando los números arbitrariamente, pero eso era solo un artefacto de tener una secuencia de 1-4. –

+2

Esto es bonito y muestra una buena comprensión de los integradores de R. +1 – Godeke

-3

bucle sobre Y y mover todo el valor emparejado en X para corregir la ubicación.

0
x <- c(2, 2, 3, 4, 1, 4, 4, 3, 3) 
y <- c(4, 2, 1, 3) 
for(i in y) { z <- c(z, rep(i, sum(x==i))) } 

El resultado en z: 4 4 4 2 2 1 3 3 3

Los pasos importantes:

  1. para (i en y) - Bucles lo largo de los elementos de interés .

  2. z < - c (z, ...) - Concatena cada subexpresión a su vez

  3. rep (i, sum (x == i)) - Repeticiones i (el elemento actual de interés) suma (x == i) veces (la cantidad de veces que encontramos i en x).

3

Se podría convertir en un factor de x ordenada:

x.factor <- factor(x, levels = y, ordered=TRUE) 
sort(x) 
sort(x.factor) 

Obviamente, cambiar sus números en factores puede cambiar radicalmente el código de manera reacciona aguas abajo a x. Pero como no nos dio ningún contexto sobre lo que sucederá a continuación, pensé que lo recomendaría como una opción.

+0

esta debería ser la mejor respuesta ya que funcionaría para casos no enteros; o también funciona cuando hay valores en 'x' que no están en el vector de clasificación' y' con un ligero cambio: 'x <- c (2, 2, 3, 4, 1, 4, 4, 3, 3, 6); y <- c (4, 2, 1, 3); as.numeric (como.caracter (sort (factor (x, unique (c (y, x)))))) ' – rawr

1

[Editar :. Es evidente que Ian tiene el enfoque correcto, pero voy a dejar esto en la posteridad]

Puede hacer esto sin bucles mediante la indexación y en su vector. Añadir sucesivamente un valor numérico a Y y fusionarlos:

y <- data.frame(index=1:length(y), x=y) 
x <- data.frame(x=x) 
x <- merge(x,y) 
x <- x[order(x$index),"x"] 
x 
[1] 4 4 4 2 2 1 3 3 3 
2

¿Qué tal si?:

rep(y,table(x)[as.character(y)]) 

(Ian es probablemente aún mejor)

111

¿qué pasa con éste

x[order(match(x,y))] 
+18

Esto es muy agradable, mejor que la respuesta aceptada en mi humilde opinión, ya que es más general. – fmark

+2

Iría tan lejos como para decir que esto debería estar en la base GNU-R. –

+0

Es muy gracioso con qué frecuencia me encuentro con esta situación y termino recurriendo a esta respuesta de una línea. Va a mostrar cómo SO puede ser útil en las cosas menos complejas jaja –

0

En caso de que necesite para conseguir el fin de la "y" no importa si se trata de números o caracteres:

x[order(ordered(x, levels = y))] 
4 4 4 2 2 1 3 3 3 

Por pasos:

a <- ordered(x, levels = y) # Create ordered factor from "x" upon order in "y". 
[1] 2 2 3 4 1 4 4 3 3 
Levels: 4 < 2 < 1 < 3 

b <- order(a) # Define "x" order that match to order in "y". 
[1] 4 6 7 1 2 5 3 8 9 

x[b] # Reorder "x" according to order in "y". 
[1] 4 4 4 2 2 1 3 3 3 
Cuestiones relacionadas