Comprendre la fonction order ()

88

J'essaie de comprendre comment order()fonctionne la fonction. J'avais l'impression qu'il retournait une permutation d'indices qui, une fois triés, trieraient le vecteur d'origine.

Par exemple,

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

Je me serais attendu à ce que cela revienne c(2, 3, 1, 4), car la liste triée serait 10 45 50 96.

Quelqu'un peut-il m'aider à comprendre la valeur de retour de cette fonction?

Jeffshantz
la source

Réponses:

100

Cela semble l'expliquer.

La définition de orderest que a[order(a)]c'est dans un ordre croissant. Cela fonctionne avec votre exemple, où l'ordre correct est le quatrième, deuxième, premier, puis troisième élément.

Vous avez peut-être cherché rank, qui renvoie le rang des éléments
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
, rankvous indique donc dans quel ordre les nombres sont, ordervous indique comment les obtenir par ordre croissant.

plot(a, rank(a)/length(a))donnera un graphique du CDF. Pour voir pourquoi orderc'est utile, essayez plot(a, rank(a)/length(a),type="S") ce qui donne un désordre, car les données ne sont pas dans l'ordre croissant

Si vous avez fait
oo<-order(a)
plot(a[oo],rank(a[oo])/length(a),type="S")
ou simplement
oo<-order(a)
plot(a[oo],(1:length(a))/length(a)),type="S")
vous obtenez un graphique linéaire du CDF.

Je parie que vous pensez au rang.

duffymo
la source
8
Ahh .. je vois maintenant. order () renvoie les indices du vecteur dans l'ordre trié. Merveilleux, merci beaucoup.
jeffshantz
order(a, decreasing = T)et rank(a)renverra une réponse équivalente.
omar
J'ai un problème avec la commande. a<-c(4,2,1,80,13)Alors order(a)devrait être 3 4 5 1 2, mais étrangement je reçois3 2 1 5 4
Shoham Debnath
1
@duffymo un peu d'aide ici serait vraiment apprécié. Quand ranket ordermême?
Shoham Debnath
En fait, order(order(a))retournera le même que rank(a) s'il n'y a pas de liens. S'il y en a, il retournera le même que rank(a, ties.method="first").
jac
33

Pour trier un vecteur 1D ou une seule colonne de données, appelez simplement la fonction de tri et transmettez votre séquence.

D'autre part, la fonction de commande est nécessaire pour trier les données à deux dimensions, c'est-à-dire plusieurs colonnes de données collectées dans une matrice ou une trame de données.

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

Voici un extrait de données pour les tentatives de buts sur le terrain lors de la saison 2008 de la NFL, une base de données que j'ai appelée «fg». supposons que ces 10 points de données représentent tous les objectifs de terrain tentés en 2008; supposons en outre que vous vouliez connaître la distance du plus long panier tenté cette année-là, qui l'a botté et s'il était bon ou non; vous voulez également connaître le deuxième plus long, ainsi que le troisième plus long, etc. et enfin, vous voulez la tentative de but sur le terrain la plus courte.

Eh bien, vous pouvez simplement faire ceci:

sort(fg$Dist, decreasing=T)

qui renvoie: 50 48 43 37 34 32 26 25 25 20

C'est correct, mais pas très utile - cela nous indique la distance de la tentative de panier la plus longue, la deuxième plus longue, ... ainsi que la plus courte; cependant, mais c'est tout ce que nous savons - par exemple, nous ne savons pas qui était le kicker, si la tentative a réussi, etc. voulez trier toutes les lignes de données sur l'attribut unique Dist . qui ressemblerait à ceci:

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

C'est ce que fait l' ordre . C'est un «tri» pour les données bidimensionnelles; en d'autres termes, il renvoie un index entier 1D composé des numéros de ligne de sorte que le tri des lignes en fonction de ce vecteur vous donnerait un tri orienté ligne correct sur la colonne, Dist

Voilà comment cela fonctionne. Ci-dessus, le tri a été utilisé pour trier la colonne Dist; pour trier le dataframe entier sur la colonne Dist, nous utilisons 'order' exactement de la même manière que 'sort' est utilisé ci - dessus :

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

(Je lie généralement le tableau retourné par 'order' à la variable 'ndx', qui signifie 'index', car je vais l'utiliser comme tableau d'index pour trier.)

c'était l'étape 1, voici l'étape 2:

'ndx', ce qui est retourné par 'sort' est ensuite utilisé comme tableau d'index pour réorganiser le dataframe, 'fg':

fg_sorted = fg[ndx,]

fg_sorted est le dataframe réordonné immédiatement au-dessus.

En somme, «sort» est utilisé pour créer un tableau d'index (qui spécifie l'ordre de tri de la colonne que vous souhaitez trier), qui est ensuite utilisé comme tableau d'index pour réorganiser la trame de données (ou la matrice).

doug
la source
2
-1: l'ordre a du sens pour un vecteur. La propriété de base de l'ordre - qu'un [ordre (a)] est trié - n'est pas clairement énoncée.
Jyotirmoy Bhattacharya
2
Faux. vous devez regarder à nouveau - la «propriété de base» est en effet montrée très clairement dans les deux lignes de code (sur fond gris) ci-dessus. Parce que le tri avec «ordre» est deux opérations distinctes, je l'ai montré en utilisant deux lignes de code - l'une créant le vecteur d'index et la deuxième ligne utilisant cet index pour effectuer le tri. Le PO a demandé une explication, pas seulement un résultat, et je lui en ai donné une, comme en témoigne le fait qu'il a sélectionné ma réponse et a écrit la brève note ci-dessus "Merci [m] a un sens parfait". J'ai même lié le résultat final à une variable appelée "fg_sorted".
doug
24

(J'ai pensé qu'il pourrait être utile de présenter les idées très simplement ici pour résumer le bon matériel publié par @doug, et lié par @duffymo; +1 à chacun, btw.)

? order vous indique quel élément du vecteur original doit être placé en premier, deuxième, etc., afin de trier le vecteur original, tandis que ? rank vous indique quel élément a la valeur la plus basse, la deuxième plus basse, etc. Par exemple:

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

Il en order(a)va de même pour dire: «mettez le troisième élément en premier lorsque vous triez ...», alors que rank(a)pour dire «le premier élément est le deuxième élément le plus bas…». (Notez qu'ils sont tous les deux d'accord sur l'élément le plus bas, etc.; ils présentent simplement les informations différemment.) Ainsi, nous voyons que nous pouvons utiliser order()pour trier, mais nous ne pouvons pas utiliser de rank()cette façon:

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

En général, order()ne sera pas égal à rank()moins que le vecteur ait déjà été trié:

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

De plus, comme il fonctionne order()(essentiellement) sur des rangs de données, vous pouvez les composer sans affecter les informations, mais l'inverse produit du charabia:

> order(rank(a))==order(a)  
[1] TRUE TRUE TRUE TRUE  
> rank(order(a))==rank(a)  
[1] FALSE FALSE FALSE  TRUE  
gung - Réintégrer Monica
la source
1
orderet ranksont en fait inverses les uns des autres (au moins tant que les valeurs de asont uniques). Si vous imaginez que chacun avait des noms (/ étiquettes) ('1', '2', '3', '4') sur leurs valeurs, alors les valeurs de order(a)vous indiquent dans quelle position dans rank(a)chaque étiquette se trouve (par exemple la 1ère valeur de order(a)(3) vous indique que «1» se produit en 3ème position de rank(a), et vice versa (par exemple, la 2ème valeur de rank(a)(3) vous indique que «2» apparaît en 3ème position de order(a)). Ce sont des permutations inverses: rank(order(a))= order(rank(a))=1 2 3 4
Glen_b
"? order vous indique quel élément du vecteur d'origine doit être placé en premier, deuxième, etc., afin de trier le vecteur d'origine, alors que? rank vous indique quel élément a la valeur la plus basse, la deuxième plus basse, etc." Là. C'est tout ce que quiconque avait à dire. Finalement. Merci!!
AleksandrH
succinctement expliqué .. ce dont on a besoin "? order vous indique quel élément du vecteur original doit être placé en premier, deuxième, etc., afin de trier le vecteur original, alors que? rank vous indique quel élément a le plus petit, le deuxième le plus bas , etc., value. "
sHiBuKaLiDhAsAn
9

L'exécution de ce petit bout de code m'a permis de comprendre la fonction de commande

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

Référence: http://r.789695.n4.nabble.com/I-don-t-understand-the-order-function-td4664384.html

adebesin
la source
1
Le résultat ne correspond pas à l'entrée. Vous devez avoir utilisé un autre xdans cbind().
Rich Scriven
Modifié par rapport aux commentaires ci-dessus. J'espère que cela aide :)
adebesin
2

Cela pourrait vous aider à un moment donné.

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

Ce que vous obtenez est

[1] 10 45 50 96

Le code que j'ai écrit indique que vous voulez "a" comme un sous-ensemble complet de "a" et que vous voulez qu'il soit ordonné de la valeur la plus basse à la plus élevée.

Alejandro Carrera
la source
2

En termes simples, order()donne les emplacements des éléments de grandeur croissante.

Par exemple, order(c(10,20,30))donnera 1,2,3 et order(c(30,20,10))donnera 3,2,1 .

Arnab Jana
la source
0

ils sont similaires mais pas identiques

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
la source
rank est la permutation inverse de l'ordre: all(x==x[order(x)][rank(x)])est toujours vrai. certaines permutations sont leur propre inverse, mais la plupart ne le sont pas. l'inverse de la permutation de tri sortant de l'ordre () est rank (). cela explique pourquoi ils sont parfois les mêmes et d'autres pas.
Nick Nassuphis le