Which.Max Ties Method in R

which.max ties method in R

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.

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

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)
}

which.max() to extract the last largest value

names(rev(test))[apply(rev(test), 1, which.max)]
[1] "M.trust" "I.trust" "I.trust" "M.trust" "M.trust" "H.trust"

R - find out if a the column containing the max value of a row is tied with another column

An option would be to get the max and check the count of max elements by row

df$tie <- apply(df[1:5], 1, function(x) sum(x == max(x)) > 1)
df$tie
#[1] FALSE FALSE TRUE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

Or using rowSums

rowSums(df[1:5] == do.call(pmax, df[1:5])) > 1
#[1] FALSE FALSE TRUE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

NOTE: Both the methods are generalized and can take care of multiple conditions

Find all tied maximum values in a row and return true or false if column contains max value

A simple and efficient solution would be to get row-wise maximum using do.call and pmax and compare it with the dataframe to get logical vectors which can be assigned as new columns.

df[paste0(names(df), "max")] <- df == do.call(pmax, df)

df
# v1 v2 v3 v4 v5 v1max v2max v3max v4max v5max
#1 0 2 4 0 0 FALSE FALSE TRUE FALSE FALSE
#2 1 1 1 1 1 TRUE TRUE TRUE TRUE TRUE
#3 2 4 6 2 6 FALSE FALSE TRUE FALSE TRUE
#4 3 7 7 7 3 FALSE TRUE TRUE TRUE FALSE
#5 4 6 8 4 6 FALSE FALSE TRUE FALSE FALSE
#6 5 7 9 5 9 FALSE FALSE TRUE FALSE TRUE
#7 6 8 0 6 8 FALSE TRUE FALSE FALSE TRUE
#8 7 9 1 7 9 FALSE TRUE FALSE FALSE TRUE
#9 8 0 2 8 0 TRUE FALSE FALSE TRUE FALSE
#10 9 1 3 9 1 TRUE FALSE FALSE TRUE FALSE

A solution with apply could be

df[paste0(names(df), "max")] <- t(apply(df, 1, function(x) x == max(x)))

Handling ties in finding index of n th maximum value in R

library(data.table)

DT<-structure(list(Refer_1 = c(11L, 15L, 7L, 19L, 104L, 24L, 11L,
22L, 39L, 19L), Refer_2 = c(17L, 21L, 13L, 25L, 204L, 36L, 14L,
25L, 45L, 37L)), .Names = c("Refer_1", "Refer_2"), row.names = c(NA,
-10L), class = c("data.table", "data.frame"), .internal.selfref = <pointer: 0x0000000000130788>)

DT[,lapply(.SD, order,decreasing=TRUE)]
Refer_1 Refer_2
1: 5 5
2: 9 9
3: 6 10
4: 8 6
5: 4 4
6: 10 8
7: 2 2
8: 1 1
9: 7 7
10: 3 3

Ties when finding minimum in R

just change which.min(df1[x,]) to which(df1[x,]==min(df1[x,])). You can even shorten your code by using apply instead of sapply

> apply(df1, 1, function(x) which(x==min(x)))
[[1]]
y
2

[[2]]
x
1

[[3]]
x y
1 2


Related Topics



Leave a reply



Submit