Entendiendo la función order ()

88

Estoy tratando de entender cómo order()funciona la función. Tenía la impresión de que devolvía una permutación de índices, que cuando se ordenaban, ordenarían el vector original.

Por ejemplo,

> a <- c(45,50,10,96)
> order(a)
[1] 3 1 2 4

Hubiera esperado que esto regresara c(2, 3, 1, 4), ya que la lista ordenada sería 10 45 50 96.

¿Alguien puede ayudarme a comprender el valor de retorno de esta función?

jeffshantz
fuente

Respuestas:

100

Esto parece explicarlo.

La definición de orderes que a[order(a)]está en orden creciente. Esto funciona con su ejemplo, donde el orden correcto es el cuarto, segundo, primero y luego tercer elemento.

Es posible que haya estado buscando rank, que devuelve el rango de los elementos,
R> a <- c(4.1, 3.2, 6.1, 3.1)
R> order(a)
[1] 4 2 1 3
R> rank(a)
[1] 3 2 4 1
por ranklo que le indica en qué orden están los números ordery cómo obtenerlos en orden ascendente.

plot(a, rank(a)/length(a))dará un gráfico de la CDF. Sin orderembargo, para ver por qué es útil, intente plot(a, rank(a)/length(a),type="S") cuál da un lío, porque los datos no están en orden creciente

Si lo hizo
oo<-order(a)
plot(a[oo],rank(a[oo])/length(a),type="S")
o simplemente
oo<-order(a)
plot(a[oo],(1:length(a))/length(a)),type="S")
obtendrá un gráfico lineal del CDF.

Apuesto a que estás pensando en el rango.

duffymo
fuente
8
Ahh .. Ya veo. order () devuelve los índices del vector en orden ordenado. Maravilloso, muchas gracias.
jeffshantz
order(a, decreasing = T)y rank(a)devolverá una respuesta equivalente.
omar
Tengo problemas con el pedido. a<-c(4,2,1,80,13)Entonces order(a)debería ser 3 4 5 1 2, pero extrañamente lo estoy recibiendo3 2 1 5 4
Shoham Debnath
1
@duffymo, una pequeña ayuda aquí sería muy apreciada. ¿Cuándo es ranky lo ordermismo?
Shoham Debnath
En realidad, order(order(a))volverá igual que rank(a) si no hubiera empates. Si los hay, devolverá lo mismo que rank(a, ties.method="first").
jac
33

Para ordenar un vector 1D o una sola columna de datos, simplemente llame a la función de ordenación y pase su secuencia.

Por otra parte, la orden función es necesaria para ordenar los datos dos datos dimensionales - es decir, múltiples columnas de datos recogidos en una matriz o trama de datos.

Stadium Home Week Qtr Away Off Def Result       Kicker Dist
751     Out  PHI   14   4  NYG PHI NYG   Good      D.Akers   50
491     Out   KC    9   1  OAK OAK  KC   Good S.Janikowski   32
702     Out  OAK   15   4  CLE CLE OAK   Good     P.Dawson   37
571     Out   NE    1   2  OAK OAK  NE Missed S.Janikowski   43
654     Out  NYG   11   2  PHI NYG PHI   Good      J.Feely   26
307     Out  DEN   14   2  BAL DEN BAL   Good       J.Elam   48
492     Out   KC   13   3  DEN  KC DEN   Good      L.Tynes   34
691     Out  NYJ   17   3  BUF NYJ BUF   Good     M.Nugent   25
164     Out  CHI   13   2   GB CHI  GB   Good      R.Gould   25
80      Out  BAL    1   2  IND IND BAL   Good M.Vanderjagt   20

Aquí hay un extracto de datos para intentos de gol de campo en la temporada 2008 de la NFL, un marco de datos que he llamado 'fg'. suponga que estos 10 puntos de datos representan todos los goles de campo intentados en 2008; además, suponga que desea saber la distancia del gol de campo más largo que se intentó ese año, quién lo pateó y si fue bueno o no; también desea conocer el segundo más largo, así como el tercero más largo, etc .; y finalmente quieres el intento de gol de campo más corto.

Bueno, podrías hacer esto:

sort(fg$Dist, decreasing=T)

que devuelve: 50 48 43 37 34 32 26 25 25 20

Eso es correcto, pero no muy útil - nos dice la distancia del intento de gol de campo más largo, el segundo más largo, ... así como el más corto; sin embargo, pero eso es todo lo que sabemos, por ejemplo, no sabemos quién fue el pateador, si el intento fue exitoso, etc. Por supuesto, necesitamos todo el marco de datos ordenado en la columna "Dist" (dicho de otra manera, desea ordenar todas las filas de datos en el atributo único Dist . que se vería así:

Stadium Home Week Qtr Away Off Def Result       Kicker Dist
751     Out  PHI   14   4  NYG PHI NYG   Good      D.Akers   50
307     Out  DEN   14   2  BAL DEN BAL   Good       J.Elam   48
571     Out   NE    1   2  OAK OAK  NE Missed S.Janikowski   43
702     Out  OAK   15   4  CLE CLE OAK   Good     P.Dawson   37
492     Out   KC   13   3  DEN  KC DEN   Good      L.Tynes   34
491     Out   KC    9   1  OAK OAK  KC   Good S.Janikowski   32
654     Out  NYG   11   2  PHI NYG PHI   Good      J.Feely   26
691     Out  NYJ   17   3  BUF NYJ BUF   Good     M.Nugent   25
164     Out  CHI   13   2   GB CHI  GB   Good      R.Gould   25
80      Out  BAL    1   2  IND IND BAL   Good M.Vanderjagt   20

Eso es lo que hace el orden . Es 'ordenado' para datos bidimensionales; dicho de otra manera, devuelve un índice entero 1D compuesto por los números de fila de modo que ordenar las filas de acuerdo con ese vector le daría una clasificación correcta orientada a filas en la columna, Dist

Así es como funciona. Por encima, una especie se utiliza para ordenar la columna Dist; para ordenar todo el marco de datos en la columna Dist, usamos 'order' exactamente de la misma manera que 'sort' se usa arriba :

ndx = order(fg$Dist, decreasing=T)

(Por lo general, asocio la matriz devuelta de 'orden' a la variable 'ndx', que significa 'índice', porque la usaré como una matriz de índice para ordenar).

ese fue el paso 1, aquí está el paso 2:

'ndx', lo que devuelve 'sort' se usa como una matriz de índice para reordenar el marco de datos, 'fg':

fg_sorted = fg[ndx,]

fg_sorted es el marco de datos reordenado inmediatamente arriba.

En resumen, 'ordenar' se usa para crear una matriz de índice (que especifica el orden de clasificación de la columna que desea ordenar), que luego se usa como una matriz de índice para reordenar el marco de datos (o matriz).

doug
fuente
2
-1: el orden tiene bastante sentido para un vector. La propiedad básica del orden - que un [orden (a)] está ordenado - no está claramente establecida.
Jyotirmoy Bhattacharya
2
Incorrecto. debe mirar nuevamente: la 'propiedad básica' se muestra muy claramente en las dos líneas de código (fondo gris) de arriba. Debido a que la clasificación con 'orden' son dos operaciones separadas, lo mostré usando dos líneas de código: una creando el vector de índice y la segunda línea usando ese índice para realizar la clasificación. El OP pidió una explicación, no solo un resultado, y yo le di una, como lo demuestra el hecho de que seleccionó mi respuesta y escribió la breve nota anterior "Gracias [m] a tiene perfecto sentido". Incluso enlacé el resultado final a una variable llamada "fg_sorted".
doug
24

(Pensé que podría ser útil presentar las ideas de manera muy simple aquí para resumir el buen material publicado por @doug y vinculado por @duffymo; +1 a cada uno, por cierto).

? order le dice qué elemento del vector original debe colocarse primero, segundo, etc., para ordenar el vector original, mientras que ? rank le dice qué elemento tiene el valor más bajo, el segundo más bajo, etc. Por ejemplo:

> a <- c(45, 50, 10, 96)
> order(a)  
[1] 3 1 2 4  
> rank(a)  
[1] 2 3 1 4  

Por order(a)lo tanto , decir, 'coloque el tercer elemento primero cuando clasifique ...', mientras que rank(a)está diciendo, 'el primer elemento es el segundo más bajo ...'. (Tenga en cuenta que ambos están de acuerdo sobre qué elemento es el más bajo, etc .; simplemente presentan la información de manera diferente). Por lo tanto, vemos que podemos usar order()para ordenar, pero no podemos usar de rank()esa manera:

> a[order(a)]  
[1] 10 45 50 96  
> sort(a)  
[1] 10 45 50 96  
> a[rank(a)]  
[1] 50 10 45 96  

En general, order()no será igual a rank()menos que el vector ya se haya ordenado:

> b <- sort(a)  
> order(b)==rank(b)  
[1] TRUE TRUE TRUE TRUE  

Además, dado order()que (esencialmente) está operando sobre rangos de datos, podría componerlos sin afectar la información, pero al revés produce un galimatías:

> order(rank(a))==order(a)  
[1] TRUE TRUE TRUE TRUE  
> rank(order(a))==rank(a)  
[1] FALSE FALSE FALSE  TRUE  
gung - Restablecer a Monica
fuente
1
ordery rankson en realidad inversos entre sí (al menos siempre que los valores de asean únicos). Si imagina que cada uno tiene nombres (/ etiquetas) ('1', '2', '3', '4') en sus valores, entonces los valores de order(a)le indican en qué posición en rank(a)cada etiqueta se encuentra (por ejemplo, el primer valor de order(a)(3) le dice que '1' ocurre en la tercera posición de rank(a), y viceversa (por ejemplo, el segundo valor de rank(a)(3) le dice que '2' ocurre en la tercera posición de order(a)). Son permutaciones inversas: rank(order(a))= order(rank(a))=1 2 3 4
Glen_b
"? order te dice qué elemento del vector original debe colocarse primero, segundo, etc., para ordenar el vector original, mientras que? rank te dice qué elemento tiene el valor más bajo, el segundo más bajo, etc." Ahí. Eso es todo lo que alguien tenía que decir. Finalmente. ¡¡Gracias!!
AleksandrH
explicado sucintamente ... lo que se necesita "? order te dice qué elemento del vector original debe colocarse primero, segundo, etc., para ordenar el vector original, mientras que? rank te dice qué elemento tiene el más bajo, el segundo más bajo , etc., valor. "
sHiBuKaLiDhAsAn
9

Ejecutar este pequeño código me permitió comprender la función de pedido

x <- c(3, 22, 5, 1, 77)

cbind(
  index=1:length(x),
  rank=rank(x),
  x, 
  order=order(x), 
  sort=sort(x)
)

     index rank  x order sort
[1,]     1    2  3     4    1
[2,]     2    4 22     1    3
[3,]     3    3  5     3    5
[4,]     4    1  1     2   22
[5,]     5    5 77     5   77

Referencia: http://r.789695.n4.nabble.com/I-don-t-understand-the-order-function-td4664384.html

adebesina
fuente
1
El resultado no coincide con la entrada. Debes haber usado uno diferente xen cbind().
Rich Scriven
Modificado con respecto a los comentarios anteriores. Espero que esto ayude :)
adebesin
2

Esto podría ayudarte en algún momento.

a <- c(45,50,10,96)
a[order(a)]

Lo que obtienes es

[1] 10 45 50 96

El código que escribí indica que quieres "a" como un subconjunto completo de "a" y quieres que esté ordenado del valor más bajo al más alto.

Alejandro Carrera
fuente
2

En palabras simples, order()da la ubicación de elementos de magnitud creciente.

Por ejemplo, order(c(10,20,30))dará 1,2,3 y order(c(30,20,10))dará 3,2,1 .

Arnab Jana
fuente
0

son similares pero no iguales

set.seed(0)
x<-matrix(rnorm(10),1)

# one can compute from the other
rank(x)  == col(x)%*%diag(length(x))[order(x),]
order(x) == col(x)%*%diag(length(x))[rank(x),]
# rank can be used to sort
sort(x) == x%*%diag(length(x))[rank(x),]
Nick Nassuphis
fuente
rango es la permutación inversa de orden: all(x==x[order(x)][rank(x)])siempre es cierto. algunas permutaciones son inversas, pero la mayoría no lo es. lo inverso a la permutación de ordenamiento que sale del orden () es rank (). esto explica por qué a veces son iguales y otras no.
Nick Nassuphis