Search code examples
rdataframedata-manipulationrank

How to make a rank column in R


I have a database with columns M1, M2 and M3. These M values correspond to the values obtained by each method. My idea is now to make a rank column for each of them. For M1 and M2, the rank will be from the highest value to the lowest value and M3 in reverse. I made the output table for you to see.

df1<-structure(list(M1 = c(400,300, 200, 50), M2 = c(500,200, 10, 100), M3 = c(420,330, 230, 51)), class = "data.frame", row.names = c(NA,-4L))

> df1
   M1  M2  M3
1 400 500 420
2 300 200 330
3 200 10 230
4  50 100  51

Output

> df1
   M1  rank M2  rank M3 rank
1 400   1   500  1   420  4    
2 300   2   200  2   330  3
3 200   3   10   4   230  2
4  50   4   100  3   51   1

Adjust rankings:

I used the code, but in a case I'm working on, my rankings looked like this: enter image description here


Solution

  • Using rank and relocate:

    library(dplyr)
    
    df1 %>% 
      mutate(across(M1:M2, ~ rank(-.x), .names = "{.col}_rank"),
             M3_rank = rank(M3)) %>% 
      relocate(order(colnames(.)))
    
       M1 M1_rank  M2 M2_rank  M3 M3_rank
    1 400       1 500       1 420       4
    2 300       2 200       2 330       3
    3 200       3  10       4 230       2
    4  50       4 100       3  51       1
    

    If you have duplicate values in your vector, then you have to choose a method for ties. By default, you get the average rank, but you can choose "first".

    Another possibility, which is I think what you want to do, is to convert to factor and then to numeric, so that you get a only entire values (not the average).

    df1 <- data.frame(M1 = c(400,300, 50, 300))
    df1 %>% 
      mutate(M1_rankAverage = rank(-M1),
             M1_rankFirst = rank(-M1, ties.method = "first"),
             M1_unique = as.numeric(as.factor(rank(-M1))))
    
       M1 M1_rankAverage M1_rankFirst M1_unique
    1 400            1.0            1         1
    2 300            2.5            2         2
    3  50            4.0            4         3
    4 300            2.5            3         2