Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are there ways to randomly sample among ties in the R function which.max()?

Tags:

r

I currently am using the which.max() function in R within a loop. Sometimes, I have a vector which contains the same elements, like:

vec <- c(0,0,2,0,2)

The function will then always return:

> which.max(vec)
[1] 3

I am wondering if there is a simple solution to break ties randomly so that it doesn't always choose the smallest index among ties. I know that there is a which.is.max function in nnet, but was hoping to see if there was another simple solution without having to resort to installing extra packages. Thanks.

like image 874
user321627 Avatar asked Mar 30 '18 07:03

user321627


2 Answers

which(vec == max(vec)) will match all ties. You can then pick one at random using sample(which(vec == max(vec)), 1).

As you mentioned in the comments, sample does something annoying when the supplied vector is of length 1. So when there is only one maximum.

You can fix this as follows:

maxima <- which(vec == max(vec))
if(length(maxima) > 1){
  maxima <- sample(maxima, 1)
}
like image 99
JAD Avatar answered Nov 19 '22 09:11

JAD


Another method is using rank with ties.method = "random" and then we can use which.max on it.

which.max(rank(vec, ties.method = "random"))

which.max(rank(vec, ties.method = "random"))
#[1] 3

which.max(rank(vec, ties.method = "random"))
#[1] 5

rank would basically rank the vector according to their value and with ties.method = "random" it will randomly assign rank in case of a tie.

rank(vec, ties.method = "random")
#[1] 2 1 4 3 5

rank(vec, ties.method = "random")
#[1] 1 3 5 2 4
like image 41
Ronak Shah Avatar answered Nov 19 '22 11:11

Ronak Shah