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.
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)
}
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With