Capire la funzione order ()


89

Sto cercando di capire come order()funziona la funzione. Avevo l'impressione che restituisse una permutazione di indici, che una volta ordinati, avrebbero ordinato il vettore originale.

Per esempio,

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

Mi sarei aspettato che questo tornasse c(2, 3, 1, 4), poiché l'elenco ordinato sarebbe 10 45 50 96.

Qualcuno può aiutarmi a capire il valore di ritorno di questa funzione?

Risposte:


101

Questo sembra spiegarlo.

La definizione di orderè che a[order(a)]è in ordine crescente. Funziona con il tuo esempio, dove l'ordine corretto è il quarto, secondo, primo, quindi terzo elemento.

Potresti aver cercato rank, che restituisce il rango degli elementi,
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
quindi rankti dice in quale ordine sono i numeri, orderti dice come ottenerli in ordine crescente.

plot(a, rank(a)/length(a))darà un grafico del CDF. Per capire perché orderè utile, però, prova a fare plot(a, rank(a)/length(a),type="S") un pasticcio, perché i dati non sono in ordine crescente

Se l'hai fatto
oo<-order(a)
plot(a[oo],rank(a[oo])/length(a),type="S")
o semplicemente
oo<-order(a)
plot(a[oo],(1:length(a))/length(a)),type="S")
ottieni un grafico a linee del CDF.

Scommetto che stai pensando al grado.


8
Ahh .. ora vedo. order () restituisce gli indici del vettore in ordine ordinato. Meraviglioso, grazie mille.
jeffshantz

order(a, decreasing = T)e rank(a)restituirà una risposta equivalente.
omar

Ho problemi con l'ordine. a<-c(4,2,1,80,13)Allora order(a)dovrebbe essere 3 4 5 1 2, ma stranamente sto ottenendo3 2 1 5 4
Shoham Debnath

1
@duffymo un piccolo aiuto qui sarebbe davvero apprezzato. Quando è ranke orderlo stesso?
Shoham Debnath

In realtà, order(order(a))restituirà lo stesso come rank(a) se non ci fossero legami. Se ci sono, restituirà lo stesso di rank(a, ties.method="first").
jac

33

Per ordinare un vettore 1D o una singola colonna di dati, basta chiamare la funzione di ordinamento e passare la sequenza.

D'altra parte, l' ordine funzione è necessaria per ordinare i dati due dati -dimensionale - cioè più colonne di dati raccolti in una matrice o dataframe.

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

Ecco un estratto dei dati per i tentativi di field goal nella stagione NFL 2008, un dataframe che ho chiamato "fg". supponiamo che questi 10 punti dati rappresentino tutti gli obiettivi sul campo tentati nel 2008; supponi inoltre di voler conoscere la distanza del canestro più lungo tentato quell'anno, chi lo ha calciato e se era buono o meno; vuoi anche conoscere il secondo più lungo, così come il terzo più lungo, ecc .; e infine vuoi il tentativo più breve di field goal.

Bene, potresti semplicemente fare questo:

sort(fg$Dist, decreasing=T)

che restituisce: 50 48 43 37 34 32 26 25 25 20

È corretto, ma non molto utile: ci dice la distanza del tentativo di canestro più lungo, il secondo più lungo, ... così come il più breve; tuttavia, ma questo è tutto ciò che sappiamo - ad esempio, non sappiamo chi fosse il kicker, se il tentativo ha avuto successo, ecc. Ovviamente, abbiamo bisogno dell'intero dataframe ordinato nella colonna "Dist" (in altre parole, noi desidera ordinare tutte le righe di dati sul singolo attributo Dist . che sarebbe simile a questo:

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

Questo è ciò che fa l' ordine . È "ordina" per dati bidimensionali; in altre parole, restituisce un indice intero 1D composto dai numeri di riga in modo tale che l'ordinamento delle righe in base a quel vettore, ti darebbe un ordinamento corretto per riga sulla colonna, Dist

Ecco come funziona. Sopra, sort è stato utilizzato per ordinare la colonna Dist; per ordinare l'intero dataframe sulla colonna Dist, usiamo 'order' esattamente nello stesso modo in cui 'sort' è usato sopra :

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

(Di solito associo l'array restituito da 'order' alla variabile 'ndx', che sta per 'index', perché lo userò come array di indice per ordinare.)

quello era il passaggio 1, ecco il passaggio 2:

'ndx', ciò che viene restituito da 'sort' viene quindi utilizzato come array di indice per riordinare il dataframe, 'fg':

fg_sorted = fg[ndx,]

fg_sorted è il dataframe riordinato immediatamente sopra.

In sintesi, "sort" viene utilizzato per creare un array di indice (che specifica l'ordinamento della colonna che si desidera ordinare), che viene quindi utilizzato come array di indice per riordinare il dataframe (o matrice).


2
-1: l'ordine ha un buon senso per un vettore. La proprietà fondamentale dell'ordine - che un [ordine (a)] è ordinato - non è chiaramente indicata.
Jyotirmoy Bhattacharya,

3
Sbagliato. devi guardare di nuovo - la 'proprietà di base' è effettivamente mostrata molto chiaramente nelle due righe di codice (sfondo grigio) sopra. Poiché l'ordinamento con "ordine" è costituito da due operazioni separate, l'ho mostrato utilizzando due righe di codice: una che crea il vettore indice e la seconda riga che utilizza quell'indice per eseguire l'ordinamento. L'OP ha chiesto una spiegazione non solo un risultato, e gliene ho data una, come dimostra il fatto che ha selezionato la mia risposta e ha scritto la breve nota sopra "Grazie [m] ha perfettamente senso". Ho persino associato il risultato finale a una variabile chiamata "fg_sorted".
Doug

24

(Ho pensato che potrebbe essere utile esporre le idee in modo molto semplice qui per riassumere il buon materiale pubblicato da @doug e collegato da @duffymo; +1 a ciascuno, btw.)

? order ti dice quale elemento del vettore originale deve essere messo per primo, secondo, ecc., in modo da ordinare il vettore originale, mentre ? rank ti dice quale elemento ha il valore più basso, secondo più basso, ecc. Per esempio:

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

Quindi order(a)sta dicendo: "metti il ​​terzo elemento per primo quando ordini ...", mentre rank(a)sta dicendo "il primo elemento è il secondo più basso ...". (Nota che entrambi concordano su quale elemento sia il più basso, ecc .; presentano le informazioni in modo diverso.) Quindi vediamo che possiamo usare order()per ordinare, ma non possiamo usare in rank()questo modo:

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

In generale, order()non sarà uguale a rank()meno che il vettore non sia già stato ordinato:

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

Inoltre, poiché opera order()(essenzialmente) sui ranghi dei dati, è possibile comporli senza influire sulle informazioni, ma il contrario produce incomprensioni:

> order(rank(a))==order(a)  
[1] TRUE TRUE TRUE TRUE  
> rank(order(a))==rank(a)  
[1] FALSE FALSE FALSE  TRUE  

1
ordere ranksono effettivamente inversi l'uno dell'altro (almeno fintanto che i valori in asono unici). Se immagini che ognuna avesse nomi (/ etichette) ('1', '2', '3', '4') sui loro valori, allora i valori di order(a)ti dicono in quale posizione si trova in rank(a)ciascuna etichetta (ad es. Il primo valore di order(a)(3) ti dice che "1" si trova nella terza posizione di rank(a), e viceversa (ad esempio, il secondo valore di rank(a)(3) ti dice che "2" si verifica nella terza posizione di order(a)). Sono permutazioni inverse: rank(order(a))= order(rank(a))=1 2 3 4
Glen_b,

"? order ti dice quale elemento del vettore originale deve essere messo per primo, secondo, ecc., in modo da ordinare il vettore originale, mentre? rank ti dice quale elemento ha il valore più basso, secondo più basso, ecc." Là. È tutto quello che chiunque ha da dire. Finalmente. Grazie!!
AleksandrH

spiegato in modo succinto .. di cosa si ha bisogno "? order ti dice quale elemento del vettore originale deve essere messo per primo, secondo, ecc., in modo da ordinare il vettore originale, mentre? rank ti dice quale elemento ha il più basso, secondo più basso , ecc., valore. "
sHiBuKaLiDhAsAn

9

L'esecuzione di questo piccolo pezzo di codice mi ha permesso di capire la funzione di ordine

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

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


1
Il risultato non corrisponde all'input. Devi aver usato un diverso xin cbind().
Rich Scriven,

Modificato per quanto riguarda i commenti di cui sopra. Spero che questo aiuti :)
adebesin

2

Questo potrebbe aiutarti a un certo punto.

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

Quello che ottieni è

[1] 10 45 50 96

Il codice che ho scritto indica che vuoi "a" come un intero sottoinsieme di "a" e vuoi che sia ordinato dal valore più basso a quello più alto.


2

In parole semplici, order() fornisce le posizioni di elementi di grandezza crescente.

Ad esempio, order(c(10,20,30))darà 1,2,3 e order(c(30,20,10))darà 3,2,1 .


0

sono simili ma non uguali

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),]

rango è la permutazione inversa dell'ordine: all(x==x[order(x)][rank(x)])è sempre vero. alcune permutazioni sono il loro inverso, ma la maggior parte non lo sono. l'inverso della permutazione di ordinamento che esce dall'ordine () è rank (). questo spiega perché a volte sono uguali e altre volte no.
Nick Nassuphis
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.