理解order()函数

95

我想理解 order() 函数的工作原理。我以为它会返回一个索引的置换,使得排序这些索引后可以对原始向量进行排序。

例如:

> a <- c(45,50,10,96)
> order(a)
[1] 3 1 2 4
我本来期望这个函数返回c(2, 3, 1, 4),因为按顺序排列后的列表应该是10 45 50 96。请问有谁可以帮我理解这个函数的返回值?
7个回答

105

这个链接似乎解释了这个问题。

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线图。

我打赌你在想rank。


8
啊..现在我明白了。order()返回向量按排序顺序排列的索引。非常好,非常感谢。 - jeffshantz
order(a, decreasing = T)rank(a)将返回相同的答案。 - omar
我在排序方面遇到了问题。 a<-c(4,2,1,80,13) 然后 order(a) 应该是 3 4 5 1 2,但奇怪的是我得到了 3 2 1 5 4 - Shoham Debnath
1
@duffymo 您的帮助将不胜感激。 何时 rankorder 是相同的? - Shoham Debnath
实际上,如果没有任何并列情况,order(order(a))将返回与rank(a)相同的结果。如果有,并列情况,它将返回与rank(a, ties.method="first")相同的结果。 - jac
假设s = sort(a),我们能否说:s == a[order(a)],并且在没有平局的情况下,a == s[rank(a)]?(不确定R语法) - djvg

34

要对一维向量或单列数据进行排序,只需调用sort函数并传入您的序列。

另一方面,order函数则是必要的,用于对二维数据进行排序 - 即,在矩阵或数据框中收集的多列数据。

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年NFL赛季中球门尝试次数的数据摘录,一个名为'fg'的数据框。假设这10个数据点代表了2008年所有的球门尝试; 进一步假设您想要知道那一年尝试的最长距离、谁踢出去的以及它是否成功; 您还想知道第二长的,以及第三长的等等; 最后,您想知道最短的球门尝试。
好吧,你可以这样做:
sort(fg$Dist, decreasing=T)

这是正确的,但并不是非常有用——它告诉我们最长的足球场进攻的距离、第二长的距离,以及最短的距离;但是,这就是我们所知道的全部——例如,我们不知道踢球者是谁,尝试是否成功等。当然,我们需要按“Dist”列对整个数据框进行排序(换句话说,我们想在单个属性 Dist 上对所有数据行进行排序)。 它看起来像这样:

返回结果: 50 48 43 37 34 32 26 25 25 20

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

这是order的作用。它是用于二维数据的'sort';换句话说,它返回一个由行号组成的1D整数索引,根据该向量对行进行排序,将为您提供正确的基于列Dist的行定向排序。
这是它的工作原理。上面使用了sort来对Dist列进行排序;要在Dist列上对整个数据框进行排序,我们使用'order',完全像上面使用'sort'一样
ndx = order(fg$Dist, decreasing=T)

通常我会将从'order'返回的数组绑定到变量'ndx'上,它代表'index',因为我将使用它作为索引数组进行排序。

这是第一步,接下来是第二步:

'sort'返回的'ndx'被用作索引数组来重新排序数据框'fg':

fg_sorted = fg[ndx,]

fg_sorted是上面立即重新排序的数据帧。

总之,'sort'用于创建索引数组(指定要排序的列的排序顺序),然后将其用作索引数组以重新排序数据帧(或矩阵)。


2
-1:对于一个向量来说,顺序是非常重要的。顺序的基本属性——即 a[order(a)] 是有序的——没有被清楚地陈述。 - Jyotirmoy Bhattacharya
3
错了。你需要再看一遍——“基本属性”确实非常清楚地显示在上面两行(灰色背景)的代码中。因为使用“order”进行排序是两个单独的操作,所以我使用了两行代码来展示——第一行创建索引向量,第二行使用该索引执行排序。OP 不仅要求得到结果,还要求解释,而我给了他解释,这也可以从他选择了我的答案,并在上面写下简短的笔记“谢谢,完全合理”可以看出。我甚至将最终结果绑定到一个名为“fg_sorted”的变量中。 - doug

26
我想在这里简单概括一下@doug发布的好材料,以及@duffymo链接的内容,希望能对大家有所帮助。?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
orderrank实际上是彼此的反函数(至少在a中的值是唯一的情况下)。如果你想象每个都有名字(/标签)('1','2','3','4'),那么order(a)的值告诉您每个标签在rank(a)中出现的位置(例如,order(a)的第一个值(3)告诉您'1'出现在rank(a)的第3个位置,反之亦然(例如,rank(a)的第二个值(3)告诉您'2'出现在order(a)的第3个位置)。它们是反置换:rank(order(a)) = order(rank(a)) = 1 2 3 4 - Glen_b
“?order告诉您需要首先放置原始向量的哪个元素,第二个元素等等,以便对原始向量进行排序,而?rank则告诉您哪个元素具有最低、第二低等值。” 就是这样。终于有人说了。谢谢! - Aleksandr Hovhannisyan
简洁地解释一下,"order"告诉你原始向量中哪个元素需要首先放置,第二个放置等等,以便对原始向量进行排序,而"rank"则告诉你哪个元素具有最低、第二低等值。 - KaLi

9
运行这段小代码让我理解了order函数的用法。
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 我不理解order函数。它是如何工作的?我看到有些代码是这样写的:
``` df[order(df$column_name), ] ```
但是我不明白`order()`函数是如何对列进行排序的,返回的结果又是什么意思。请帮忙解释一下。

1
结果与输入不匹配。你肯定在 cbind() 中使用了不同的 x - Rich Scriven
根据上述评论进行了修改。希望这有所帮助 :) - kazuwal

2

简单来说,order() 函数会返回元素按大小排序后的位置。

例如,order(c(10,20,30)) 将会返回 1,2,3,而 order(c(30,20,10)) 将会返回 3,2,1


2
这可能在某些时候对你有所帮助。
a <- c(45,50,10,96)
a[order(a)]

你将得到的是:
[1] 10 45 50 96

我写的代码表示您想要将“a”作为整个子集,并且您希望按从最低到最高值的顺序对其进行排序。

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

排名是顺序的逆置:all(x==x[order(x)][rank(x)]) 总是成立的。有些排列是它们自己的逆置,但大多数不是。从 order() 出来的排序排列的逆置是 rank()。这就解释了为什么它们有时相同,有时不同。 - Nick Nassuphis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接