1

Consider the following simple example:

df <- data.frame(score1 = c(10, 12, 19, 13),
                 score2 = c(13, 10, 16, 12),
                 score3 = c(10, 10, 19, 15),
                 score4 = c(11, 14, 17, 15))

I want to: (i) work out for each row of data, which score is the highest (ii) in the event of a tie for the highest score, favour lower score numbers (eg in a tie between score1 and score2, score1 wins)

I can do this:

df$max_score <- pmax(df$score1, df$score2, df$score3, df$score4)

df$winning_score_name <- ifelse(df$score1 >= df$max_score,
                                "score1",
                                ifelse(df$score2 >= df$max_score,
                                      "score2",
                                      ifelse(df$score3 >= df$max_score,
                                             "score3",
                                             "score4")))

and df$winning_score_name gives me:

[1] "score2" "score4" "score1" "score3"

...but in the real world example I'm working with (which has many score columns), this would be very hard to read & to maintain. Is there a more concise way to code this pls?

Thank you.

Alan
  • 619
  • 6
  • 19
  • 4
    `names(df)[max.col(df, ties.method = "first")]` should do it. – Ritchie Sacramento Mar 03 '20 at 09:08
  • 1
    ties.method = “first” !!! This stuff is so simple sometimes...thank you very much. I will try it shortly. – Alan Mar 03 '20 at 09:14
  • Just for what it's worth, a chaining piece of data.table `dt1[, rowID := 1:4][, .(maxValue = colnames(dt1)[which.max(.SD)]), .SDcols = colnames(dt1), by = rowID][, maxValue]` – rg255 Mar 03 '20 at 10:10

0 Answers0