which.max ties method in R

by0 picture by0 · Mar 26, 2013 · Viewed 23.9k times · Source

which.max and which.min will return the smallest index of the max or min value if there are ties.

Is there a way around this so that the largest index is returned without affecting the efficiency of the function?

max.col has this exact functionality, but I am dealing with a vector not a matrix.

Answer

Jouni Helske picture Jouni Helske · Mar 26, 2013

You could do like this:

x<-c(1,2,1,4,3,4)
#identical to which.max, except returns all indices with max
which(x==max(x)) 
[1] 4 6
z<-which(x==max(x))
z[length(z)]
[1] 6
#or with tail
tail(which(x==max(x)),1)
[1] 6

edit:

Or, you could also use max.col function for vectors like this:

max.col(t(x),"last")
[1] 6
#or
max.col(matrix(x,nrow=1),"last")
[1] 6

edit: Some benchmarking:

x<-sample(1:1000,size=10000,replace=TRUE)
library(microbenchmark)
microbenchmark(which.max(x),{z<-which(x==max(x));z[length(z)]}, 
     tail(which(x==max(x)),1),max.col(matrix(x,nrow=1),"last"),
     max.col(t(x),"last"),which.max(rev(x)),times=1000)
Unit: microseconds
                                             expr     min      lq  median      uq       max neval
                                     which.max(x)  29.390  30.323  30.323  31.256 17550.276  1000
 {     z <- which(x == max(x))     z[length(z)] }  40.586  42.452  42.919  44.318   631.178  1000
                      tail(which(x == max(x)), 1)  57.380  60.646  61.579  64.844   596.657  1000
             max.col(matrix(x, nrow = 1), "last") 134.353 138.085 139.485 144.383   710.949  1000
                            max.col(t(x), "last") 116.159 119.425 121.291 125.956   729.610  1000
                                which.max(rev(x))  89.569  91.435  92.368  96.566   746.404  1000

So all methods seem to be slower than the original (which gives wrong result), but z <- which(x == max(x));z[length(z)] seems to be fastest option of these.