如何在R中制作排名列

问题描述 投票:0回答:4

我有一个包含列

M1
M2
M3
的数据库。这些M值对应于通过每种方法获得的值。我现在的想法是为他们每个人制作一个排名列。对于
M1
M2
,排名将从最高值到最低值,而
M3
则相反。我做了输出表给你看。

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

调整排名:

我使用了代码,但在我正在处理的情况下,我的排名如下所示: enter image description here

r dataframe data-manipulation rank
4个回答
7
投票

使用

rank
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

如果向量中有重复值,那么您必须选择一种联系方法。默认情况下,您获得平均排名,但您可以选择“第一”。

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

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

0
投票

要实现此结果,我要做的是将每个 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))))

0
投票

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

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

0
投票
library(data.table)

# Assuming df1 is already a data.table
setDT(df1)

df1[, `:=`(
  Rank1 = as.numeric(as.factor(M1)),
  Rank2 = as.numeric(as.factor(M2)),
  Rank3 = as.numeric(fct_rev(as.factor(M3)))
)]
© www.soinside.com 2019 - 2024. All rights reserved.