Розуміння функції order ()


88

Я намагаюся зрозуміти, як order()працює ця функція. У мене склалося враження, що воно повертає перестановку індексів, яка при сортуванні буде сортувати вихідний вектор.

Наприклад,

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

Я би очікував, що це повернеться c(2, 3, 1, 4), оскільки відсортований список буде 10 45 50 96.

Хтось може допомогти мені зрозуміти повернене значення цієї функції?

Відповіді:


100

Це , здається, пояснити.

Визначення orderє те , що a[order(a)]це в порядку зростання. Це працює з вашим прикладом, де правильним порядком є ​​четвертий, другий, перший, потім третій елемент.

Можливо, ви шукали rank, що повертає ранг елементів,
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
щоб rankповідомити вам, у якому порядку знаходяться числа, і orderрозповісти, як отримати їх у порядку зростання.

plot(a, rank(a)/length(a))дасть графік CDF. orderОднак, щоб зрозуміти, чому це корисно, спробуйте, plot(a, rank(a)/length(a),type="S") що спричиняє безлад, оскільки дані не зростають

Якщо ви це зробили
oo<-order(a)
plot(a[oo],rank(a[oo])/length(a),type="S")
або просто
oo<-order(a)
plot(a[oo],(1:length(a))/length(a)),type="S")
отримаєте лінійний графік CDF.

Б'юся об заклад, ви думаєте про звання.


8
Ааа .. я бачу зараз. order () повертає індекси вектора у відсортованому порядку. Чудово, велике спасибі.
jeffshantz

order(a, decreasing = T)і rank(a)поверне еквівалентну відповідь.
омар,

У мене проблеми з замовленням. a<-c(4,2,1,80,13)Тоді order(a)повинно бути 3 4 5 1 2, але як не дивно, я отримую3 2 1 5 4
Шохам Дебнат

1
@duffymo невелика допомога тут була б дуже вдячна. Коли це rankі те orderсаме?
Шохам Дебнат

Насправді, order(order(a))повернеться так само, як rank(a) ніби немає зв'язків. Якщо є, він поверне те саме, що і rank(a, ties.method="first").
jac

33

Щоб відсортувати одновимірний вектор або окремий стовпець даних, просто викликайте функцію сортування та передайте свою послідовність.

З іншого боку, порядок функції необхідно сортувати дані два мірних даних - тобто, декілька стовпців даних , зібраних в матриці або 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

Ось фрагмент даних для спроб польових воріт у сезоні НФЛ 2008, фрейм даних, який я назвав "fg". припустимо, що ці 10 пунктів даних представляють усі цілі на місцях, які були зроблені в 2008 році; далі припустимо, ви хочете знати відстань найдовшого польового гола, який намагався здійснити в тому році, хто його вдарив, і чи був він хорошим чи ні; ви також хочете знати другий за довжиною, а також третій за довжиною тощо; і нарешті вам потрібна найкоротша спроба польових воріт.

Ну, ви можете просто зробити це:

sort(fg$Dist, decreasing=T)

який повертає: 50 48 43 37 34 32 26 25 25 20

Це правильно, але не дуже корисно - воно насправді повідомляє нам відстань найдовшої спроби польових воріт, другої за довжиною, ... а також найкоротшої; проте, але це все, що ми знаємо - наприклад, ми не знаємо, ким був кикер, чи була спроба успішною тощо. Звичайно, нам потрібен весь кадр даних, відсортований у стовпці "Dist" (по-іншому, ми хочу відсортувати всі рядки даних на одному атрибуті Dist ., який виглядатиме так:

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

Це те , що робить порядок . Це "сортування" для двовимірних даних; по-іншому, він повертає одновимірний цілочисельний індекс, що складається з номерів рядків, так що сортування рядків відповідно до цього вектора дасть вам правильне орієнтоване на рядки сортування в стовпці, Dist

Ось як це працює. Вище сортування використовувалось для сортування стовпця Dist; щоб відсортувати весь кадр даних у стовпці Dist, ми використовуємо 'order' точно так само, як і 'sort', що використовується вище :

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

(я зазвичай прив'язую масив, повернутий із "замовлення", до змінної "ndx", що означає "індекс", оскільки я збираюся використовувати його як масив індексу для сортування.)

це був крок 1, ось крок 2:

'ndx', те, що повертається 'sort', потім використовується як масив індексу для переупорядкування кадру даних, 'fg':

fg_sorted = fg[ndx,]

fg_sorted - це впорядкований фрейм даних безпосередньо вище.

Підсумовуючи, сортування використовується для створення масиву індексу (який визначає порядок сортування стовпця, який потрібно відсортувати), який потім використовується як масив індексу для переупорядкування кадру даних (або матриці).


2
-1: порядок має досить хороший сенс для вектора. Основна властивість порядку - це те, що [порядок (а)] відсортовано - чітко не зазначено.
Jyotirmoy Bhattacharya

2
Неправильно. Вам потрібно ще раз подивитися - „основна властивість“ справді дуже чітко показано у двох (сірих) рядках коду вище. Оскільки сортування за "порядком" - це дві окремі операції, я показав це, використовуючи два рядки коду - один, що створює вектор індексу, і другий рядок, який використовує цей індекс для виконання сортування. ОП попросив пояснити не просто результат, і я дав йому одне, про що свідчить той факт, що він вибрав мою відповідь і написав коротку замітку вище "Спасибі [m], цілком зрозуміло". Я навіть прив'язав кінцевий результат до змінної, яка називається "fg_sorted".
дуг

24

(Я вважав, що може бути корисно викласти ідеї дуже просто тут, щоб узагальнити хороший матеріал, розміщений @doug та зв'язаний @duffymo; +1 кожному, до речі.)

? order вказує, який елемент вихідного вектора потрібно поставити першим, другим тощо, щоб відсортувати вихідний вектор, тоді як ? rank повідомляє, який елемент має найменше, друге найнижче значення тощо. Наприклад:

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

Так само, order(a)як кажуть, "поставте третій елемент першим, коли ви сортуєте ...", тоді rank(a)як говорите, "перший елемент - другий найнижчий ...". (Зверніть увагу, що вони обидва домовляються про те, який елемент найнижчий тощо; вони просто подають інформацію по-різному.) Таким чином, ми бачимо, що ми можемо використовувати order()сортування, але ми не можемо використовувати rank()такий спосіб:

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

Загалом, order()не буде рівним, rank()якщо вектор вже не відсортовано:

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

Крім того, оскільки order()(по суті) оперує рядами даних, ви можете складати їх, не впливаючи на інформацію, але навпаки, це створює незграбність:

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

1
orderі rankнасправді є оберненими значеннями один одного (принаймні, поки значення в aунікальні). Якщо ви уявляєте, що кожен з них мав імена (/ мітки) ('1', '2', '3', '4') на своїх значеннях, тоді значення order(a)вказують вам, в якому місці знаходиться rank(a)кожна мітка (наприклад, 1-е значення order(a)(3) повідомляє, що "1" зустрічається в 3-й позиції rank(a), і навпаки (наприклад, 2-е значення rank(a)(3) говорить, що "2" зустрічається в 3-й позиції order(a)). Вони є зворотними перестановками: rank(order(a))= order(rank(a))=1 2 3 4
Glen_b

"? order вказує вам, який елемент вихідного вектора потрібно поставити першим, другим тощо, щоб відсортувати оригінальний вектор, тоді як? rank повідомляє, який елемент має найменше, друге найнижче значення." Там. Це все, що хтось мав сказати. Нарешті. Дякую!!
AleksandrH

коротко пояснений .. що кому потрібно "? порядок говорить вам, який елемент вихідного вектора потрібно поставити першим, другим тощо, щоб відсортувати вихідний вектор, тоді як? rank - вам, який елемент має найнижчий, другий найнижчий та ін., значення. "
sHiBuKaLiDhAs

9

Запуск цього невеликого фрагмента коду дозволив мені зрозуміти функцію замовлення

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

Посилання: http://r.789695.n4.nabble.com/I-don-t-understand-the-order-function-td4664384.html


1
Результат не відповідає введеному. Ви, мабуть, використовували інший xв cbind().
Rich Scriven

Змінено стосовно вищезазначених коментарів. Сподіваюся, це допомагає :)
adebesin

2

Це може допомогти вам у певний момент.

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

Що ти отримуєш

[1] 10 45 50 96

Код, який я написав, вказує, що ви хочете "a" як цілу підмножину "a", і ви хочете, щоб він був упорядкований від найменшого до найвищого значення.


2

Простими словами, order()дає розташування елементів зростаючої величини.

Наприклад, order(c(10,20,30))дасть 1,2,3 і order(c(30,20,10))дасть 3,2,1 .


0

вони схожі, але не однакові

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

rank є оберненою перестановкою порядку: all(x==x[order(x)][rank(x)])завжди є істинним. деякі перестановки є власними зворотними, але більшість - ні. зворотна перестановка для сортування, що виходить із порядку (), є рангом (). це пояснює, чому вони іноді однакові, а інколи ні.
Нік Нассуфіс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.