92 votes

Comprendre la fonction order()

J'essaie de comprendre comment le order() fonctionne. J'avais l'impression qu'elle renvoyait une permutation d'indices qui, une fois triée, trierait le vecteur original.

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) puisque la liste triée serait 10 45 50 96.

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

104voto

duffymo Points 188155

Ce site semble l'expliquer.

La définition de order c'est que a[order(a)] est en ordre croissant. Cela fonctionne avec votre exemple, où l'ordre correct 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
donc rank vous indique dans quel ordre se trouvent les chiffres, order vous indique comment les obtenir dans l'ordre croissant.

plot(a, rank(a)/length(a)) donnera un graphique de la CDF. Pour voir pourquoi order est utile, mais essayez plot(a, rank(a)/length(a),type="S") ce qui donne un désordre, car les données ne sont pas en ordre croissant

Si vous l'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 de la CDF.

Je parie que vous pensez au rang.

8 votes

Ahh je vois maintenant. order() renvoie les indices du vecteur dans l'ordre trié. Merveilleux, merci beaucoup.

0 votes

order(a, decreasing = T) et rank(a) renverra une réponse équivalente.

0 votes

J'ai un problème avec la commande. a<-c(4,2,1,80,13) Puis order(a) devrait être 3 4 5 1 2 mais bizarrement, j'obtiens 3 2 1 5 4

33voto

doug Points 29567

Pour trier un vecteur 1D ou une seule colonne de données, il suffit d'appeler la fonction trier et passer dans votre séquence.

D'autre part, le commander La fonction est nécessaire pour trier les données deux -Les données multidimensionnelles, c'est-à-dire les colonnes multiples de données rassemblées dans une matrice ou un cadre 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

Supposons que ces 10 points de données représentent tous les field goals tentés en 2008. Supposons également que vous souhaitiez connaître la distance du plus long field goal tenté cette année-là, qui l'a botté et s'il a été bon ou mauvais.

Eh bien, tu pourrais juste faire ça :

sort(fg$Dist, decreasing=T)

qui donne : 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 plus longue tentative de field goal, la deuxième plus longue,... ainsi que la plus courte ; cependant, c'est tout ce que nous savons - par exemple, nous ne savons pas qui était le botteur, si la tentative a été réussie, etc. Bien sûr, nous avons besoin de l'ensemble du cadre de données trié sur la colonne "Dist" (en d'autres termes, nous voulons trier toutes les lignes de données sur l'unique attribut 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 commander fait. Il s'agit d'un "tri" pour les données bidimensionnelles ; en d'autres termes, il renvoie un indice entier 1D composé des numéros de rangée de telle sorte que le tri des rangées en fonction de ce vecteur vous donne un tri correct orienté rangée sur la colonne, Dist

Voici comment cela fonctionne. Ci-dessus, trier a été utilisé pour trier la colonne Dist ; pour trier l'ensemble du cadre de données 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 habituellement le tableau retourné par 'order' à la variable 'ndx', qui signifie 'index', parce que je vais l'utiliser comme tableau d'indexation pour s'assurer que le tableau n'est pas endommagé). pour 'index', parce que je vais l'utiliser comme un tableau d'index pour trier).

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

ndx', ce qui est renvoyé par 'sort' est ensuite utilisé comme un tableau d'index pour réorganiser le cadre de données, 'fg' :

fg_sorted = fg[ndx,]

fg_sorted est le cadre de données réordonné immédiatement au-dessus.

En résumé, "sort" est utilisé pour créer un tableau d'index (qui spécifie l'ordre de tri de la colonne que vous voulez trier), qui est ensuite utilisé comme tableau d'index pour réorganiser le cadre de données (ou la matrice).

2 votes

-1 : l'ordre est assez logique pour un vecteur. La propriété de base de order - à savoir que a[order(a)] est trié - n'est pas clairement énoncée.

3 votes

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 et l'ordre sont deux opérations distinctes, je l'ai montré en utilisant deux lignes de code - l'une créant le vecteur d'index et la seconde utilisant cet index pour effectuer le tri. L'OP a demandé une explication et pas seulement un résultat, et je lui en ai donné une, comme le prouve le fait qu'il a sélectionné ma réponse et écrit la brève note ci-dessus "Thanks [m]akes perfect sense". J'ai même lié le résultat final à une variable appelée "fg_sorted".

25voto

gung Points 2999

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

?commande vous indique quel élément du vecteur original doit être placé en premier, en second, etc. afin de trier le vecteur original, alors que ?rang 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  

Alors order(a) dit, "mettez le troisième élément en premier quand vous triez...", alors que rank(a) dit : "le premier élément est le deuxième plus bas...". (Notez qu'ils sont tous deux d'accord pour dire quel élément est le plus bas, etc. ; ils présentent simplement l'information différemment). Nous voyons donc que nous pouvons utiliser order() pour trier, mais nous ne pouvons pas utiliser rank() de 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() sauf si le vecteur a déjà été trié :

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

En outre, étant donné que order() opère (essentiellement) sur les rangs des données, vous pourriez les composer sans affecter l'information, 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

1 votes

order et rank sont en fait des inverses l'un de l'autre (du moins tant que les valeurs de l'option a sont uniques). Si vous imaginez que chacun d'entre eux a des noms(/labels) ('1', '2', '3', '4') sur leurs valeurs, alors les valeurs de order(a) vous indique quelle position dans rank(a) dans laquelle chaque étiquette apparaît (par exemple, la 1ère valeur de order(a) (3) vous dit que '1' se trouve en 3ème position de rank(a) et vice versa (par exemple, la 2e valeur de rank(a) (3) vous dit que '2' se trouve en 3ème position de order(a) ). Ce sont des permutations inverses : rank(order(a)) = order(rank(a)) = 1 2 3 4

0 votes

" ?order vous indique quel élément du vecteur original doit être placé en premier, en second, etc., de manière à trier le vecteur original, alors que ?rank vous indique quel élément a la valeur la plus basse, la deuxième plus basse, etc.". Voilà. C'est tout ce qu'on avait à dire. Enfin. Merci !

0 votes

explique succinctement ce dont on a besoin " ?order vous indique quel élément du vecteur original doit être placé en premier, en second, 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. "

9voto

adebesin Points 557

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

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

1 votes

Le résultat ne correspond pas à l'entrée. Vous avez dû utiliser un autre x en cbind() .

0 votes

Modifié en fonction des commentaires ci-dessus. J'espère que cela vous aidera :)

2voto

Alejandro Carrera Points 185

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 que "a" soit un sous-ensemble entier de "a" et que vous voulez qu'il soit ordonné de la plus petite à la plus grande valeur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X