如何在R中制作排名列

How to make a rank column in R

我有一个包含列 M1M2M3 的数据库。这些 M 值对应于每种方法获得的值。我现在的想法是为他们每个人制作一个排名列。对于M1M2,排名将从最高值到最低值,M3相反。我做了输出table给你看。

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

输出

> 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

调整排名:

我使用了代码,但在我处理的案例中,我的排名如下所示:

使用 rankrelocate:

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

如果您的向量中有重复值,则必须选择一种方法来计算并列值。默认情况下,您获得平均排名,但您可以选择“第一”。

另一种可能性,我想你想做的是先转换为因子,然后再转换为数字,这样你就只能得到一个完整的值(而不是平均值)。

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

要实现此结果,我会做的是将每个 df 列转换为因子,然后再次将它们转换为数字。这可以在基本 R 中完成,但为了简单起见,我报告了 tidyverse 代码:

library(tidyverse)

df1 = df1 %>% 
  mutate(Rank1 = as.numeric(as.factor(M1))) %>% 
  mutate(Rank2 = as.numeric(as.factor(M2))) %>% 
  mutate(Rank3 = as.numeric(fct_rev(as.factor(M3))))

另一种可能的解决方案,基于dplyr

library(dplyr)

df1 %>% 
  mutate(across(-3, ~ dense_rank(desc(.x)), .names = "{.col}_rank"),
         across(3, ~ dense_rank(.x), .names = "{.col}_rank")) %>% 
  relocate(sort(names(.)))

#>    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