Sandy
Sandy

Reputation: 1148

which.max() to extract the last largest value

In my code, I want to extract the last largest value across a range of columns, iterating row-wise over the data frame. The problem is that my script only gives me the first occurrence (name of the first column in this case) that has the maximum value. Any suggestions on how I can update this line to get the last maximum value?

My data frame looks like this:

A.trust B.trust C.trust D.trust E.trust F.trust G.trust H.trust I.trust J.trust K.trust L.trust M.trust
-999    -999    -999    -999    -999    -999    -999.0  -999.0  -999.0   -999   -999    -999    -999
-999    -999    -999    -999    -999    -999     0.5    -999.0   0.5     -999   -999    -999    -999
-999    -999    -999    -999    -999    -999    -999.0  -999.0   1.0     -999   -999    -999    -999
-999    -999    -999    -999    -999    -999    -999.0  -999.0  -999.0   -999   -999    -999    -999
-999    -999    -999    -999    -999    -999    -999.0  -999.0  -999.0   -999   -999    -999    -999
-999    -999    -999    -999    -999    -999     0.5     0.5    -999.0   -999   -999    -999    -999

I am using the following code

# return cols which hold maximum
nams <- names(test)[apply(test, 1 ,which.max)]

Current Output

Currently, the value in the nams variable is:

"A.trust"
"G.trust" 
"I.trust" 
"A.trust"
"A.trust" 
"G.trust"

Required Output

My required value in the nams variable is this:

"M.trust" 
"I.trust" 
"I.trust"
"M.trust" 
"M.trust" 
"H.trust"

dput()

test = structure(list(A.trust = c(-999, -999, -999, -999, -999, -999), 
               B.trust = c(-999, -999, -999, -999, -999, -999), 
               C.trust = c(-999, -999, -999, -999, -999, -999), 
               D.trust = c(-999, -999, -999, -999, -999, -999), 
               E.trust = c(-999, -999, -999, -999, -999, -999), 
               F.trust = c(-999, -999, -999, -999, -999, -999), 
               G.trust = c(-999,  0.5, -999, -999, -999,  0.5), 
               H.trust = c(-999, -999, -999, -999, -999,  0.5), 
               I.trust = c(-999,  0.5,  1,   -999, -999, -999), 
               J.trust = c(-999, -999, -999, -999, -999, -999), 
               K.trust = c(-999, -999, -999, -999, -999, -999), 
               L.trust = c(-999, -999, -999, -999, -999, -999), 
               M.trust = c(-999, -999, -999, -999, -999, -999)), 
          row.names = 600:605, class = "data.frame")

Related Posts

The following post is relevant to my problem but I am struggling with how to make this change in my script How to find the last occurrence of a certain observation in grouped data in R?. This is another related post which.max ties method in R. Any help would be greatly appreciated!

Upvotes: 0

Views: 1465

Answers (3)

Ben Bolker
Ben Bolker

Reputation: 226097

Another possibility (probably less efficient than @Skaqqs's answer):

names(test)[apply(test, 1, function(x) tail(which(x == max(x)), 1)]

Upvotes: 2

akrun
akrun

Reputation: 886948

We may use vectorized option

 names(test)[ncol(test):1][max.col(rev(test), "first")]
[1] "M.trust" "I.trust" "I.trust" "M.trust" "M.trust" "H.trust"

Upvotes: 1

Skaqqs
Skaqqs

Reputation: 4140

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

Upvotes: 5

Related Questions