57

i am having trouble understanding the difference between the R function rank and the R function order. they seem to produce the same output:

> rank(c(10,30,20,50,40))
[1] 1 3 2 5 4
> order(c(10,30,20,50,40))
[1] 1 3 2 5 4

Could somebody shed some light on this for me? Thanks

zx8754
  • 52,746
  • 12
  • 114
  • 209
Alex
  • 19,533
  • 37
  • 126
  • 195
  • 3
    A blog post about this is: http://www.portfolioprobe.com/2012/07/26/r-inferno-ism-order-is-not-rank/ – Patrick Burns Sep 06 '12 at 08:32
  • 1
    I also wrote a [blog post](https://ro-che.info/articles/2016-03-19-rank-vs-order-r) about this. In particular, I try to explain why the OP is seeing identical results from `rank` and `order`. – Roman Cheplyaka Mar 19 '16 at 01:02
  • Possible duplicate of [Understanding the order() function](http://stackoverflow.com/questions/2315601/understanding-the-order-function) – user May 12 '17 at 02:45

7 Answers7

73
set.seed(1)
x <- sample(1:50, 30)    
x
# [1] 14 19 28 43 10 41 42 29 27  3  9  7 44 15 48 18 25 33 13 34 47 39 49  4 30 46  1 40 20  8
rank(x)
# [1]  9 12 16 25  7 23 24 17 15  2  6  4 26 10 29 11 14 19  8 20 28 21 30  3 18 27  1 22 13  5
order(x)
# [1] 27 10 24 12 30 11  5 19  1 14 16  2 29 17  9  3  8 25 18 20 22 28  6  7  4 13 26 21 15 23

rank returns a vector with the "rank" of each value. the number in the first position is the 9th lowest. order returns the indices that would put the initial vector x in order.

The 27th value of x is the lowest, so 27 is the first element of order(x) - and if you look at rank(x), the 27th element is 1.

x[order(x)]
# [1]  1  3  4  7  8  9 10 13 14 15 18 19 20 25 27 28 29 30 33 34 39 40 41 42 43 44 46 47 48 49
andschar
  • 3,504
  • 2
  • 27
  • 35
Justin
  • 42,475
  • 9
  • 93
  • 111
13

As it turned out this was a special case and made things confusing. I explain below for anyone interested:

rank returns the order of each element in an ascending list

order returns the index each element would have in an ascending list

Alex
  • 19,533
  • 37
  • 126
  • 195
8

I always find it confusing to think about the difference between the two, and I always think, "how can I get to order using rank"?

Starting with Justin's example:

Order using rank:

## Setup example to match Justin's example
set.seed(1)
x <- sample(1:50, 30) 

## Make a vector to store the sorted x values
xx = integer(length(x))

## i is the index, ir is the ith "rank" value
i = 0
for(ir in rank(x)){
    i = i + 1
    xx[ir] = x[i]
}

all(xx==x[order(x)])
[1] TRUE
geneorama
  • 3,620
  • 4
  • 30
  • 41
6

rank is more complicated and not neccessarily an index (integer):

> rank(c(1))
[1] 1
> rank(c(1,1))
[1] 1.5 1.5
> rank(c(1,1,1))
[1] 2 2 2
> rank(c(1,1,1,1))
[1] 2.5 2.5 2.5 2.5
sau
  • 61
  • 1
  • 1
6

In layman's language, order gives the actual place/position of a value after sorting the values For eg:

a<-c(3,4,2,7,8,5,1,6)
sort(a) [1] 1 2 3 4 5 6 7 8

The position of 1 in a is 7. similarly position of 2 in a is 3.

order(a) [1] 7 3 1 2 6 8 4 5
Mr. T
  • 11,960
  • 10
  • 32
  • 54
user9476132
  • 61
  • 1
  • 1
1

as is stated by ?order() in R prompt, order just return a permutation which sort the original vector into ascending/descending order. suppose that we have a vector

A<-c(1,4,3,6,7,4);
A.sort<-sort(A);

then

order(A) == match(A.sort,A);
rank(A) == match(A,A.sort);

besides, i find that order has the following property(not validated theoratically):

1 order(A)∈(1,length(A))
2 order(order(order(....order(A)....))):if you take the order of A in odds number of times, the results remains the same, so as to even number of times.
ewre
  • 61
  • 4
0

some observations:

set.seed(0)
x<-matrix(rnorm(10),1)
dm<-diag(length(x))

# compute  rank from order and backwards:
rank(x)  == col(x)%*%dm[order(x),]
order(x) == col(x)%*%dm[rank(x),]


# in special cases like this
x<-cumsum(rep(c(2,0),times=5))+rep(c(0,-1),times=5)
# they are equal
order(x)==rank(x)

Nick Nassuphis
  • 257
  • 2
  • 6
  • ``diag(length(x))[order(x),]==t(diag(length(x))[rank(x),])`` is the relationship between rank and order – Nick Nassuphis Jan 17 '20 at 10:22
  • rank() is the inverse permutation to order(). some permutations are their own inverse and it is in these cases that ``order(x)==rank(x)``. In general, ``all(x==x[order(x)][rank(x)])`` always holds. – Nick Nassuphis Jan 17 '20 at 19:01