web-dev-qa-db-fra.com

Comprendre la fonction order ()

J'essaie de comprendre comment fonctionne la fonction order(). J'avais l'impression qu'il renvoyait 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 retourne c(2, 3, 1, 4), puisque la liste triée serait 10 45 50 96.

Est-ce que quelqu'un peut m'aider à comprendre la valeur de retour de cette fonction?

77
jeffshantz

This semble l'expliquer.

La définition de order est que a[order(a)] est en 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
donc rank vous indique dans quel ordre se trouvent les nombres, order vous indique comment les obtenir par ordre croissant.

plot(a, rank(a)/length(a)) donnera un graphique du CDF. Pour voir pourquoi order est utile, essayez cependant plot(a, rank(a)/length(a),type="S") qui donne le bazar, 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 songez au rang.

92
duffymo

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

D'autre part, la fonction order est nécessaire pour trier les données deux - données dimensionnelles - 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 des données relatives aux tentatives d'objectifs de la saison 2008 de la NFL, une trame 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 souhaitiez connaître la distance du plus long placement sur le terrain tenté cette année-là, qui l'a lancé et si c'était bon ou non; vous voulez aussi connaître le deuxième plus long, ainsi que le troisième plus long, etc. et enfin vous voulez la plus courte tentative d'objectifs.

Eh bien, vous pouvez simplement faire ceci:

sort(fg$Dist, decreasing=T)

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

C'est correct, mais pas très utile - cela nous indique la distance de la plus longue tentative de placement sur le terrain, 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é un succès, etc. Bien sûr, nous avons besoin de l’ensemble du cadre de données trié dans la colonne "Dist" vouloir trier toutes les lignes de données sur l'attribut unique Dist . Cela 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 ordre fait. C'est un "tri" pour les données à deux dimensions; En d'autres termes, elle 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 correct, orienté ligne sur la colonne, Dist

Voici comment cela fonctionne. Ci-dessus, sort a été utilisé pour trier la colonne Dist; pour trier l'intégralité du cadre de données sur la colonne Dist, nous utilisons 'order' 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 renvoyé de 'order' à la variable 'ndx', qui signifie 'index', parce que je vais l'utiliser comme un tableau d'index à 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éordonner le cadre de données, 'fg':

fg_sorted = fg[ndx,]

fg_sorted est la trame de données réorganisée immédiatement ci-dessus.

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

32
doug

(J'ai pensé qu'il serait peut-être utile de présenter les idées très simplement ici pour résumer le bon matériel posté par @doug, et lié par @duffymo; +1 à chaque, en fait.)

? order vous indique quel élément du vecteur d'origine doit être placé en premier, second, etc., afin de trier le vecteur d'origine, 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  

Donc, order(a) dit: 'placez le troisième élément en premier lorsque vous triez ...', alors que rank(a) dit: 'le premier élément est le deuxième plus bas ...'. (Notez qu'ils sont tous les deux d’accord sur l’élément le plus bas, etc.; ils ne font que présenter les informations 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  

De plus, étant donné que order() opère (essentiellement) sur plusieurs rangs de données, vous pouvez les composer sans affecter l'information, mais l'inverse produit un charabia:

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

Utiliser ce petit morceau 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

6
adebesin

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

2

En termes simples, order() donne les emplacements des éléments de plus en plus importants.

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

1
Arnab Jana