如何在R中制作排名列

发布于 2025-01-12 09:37:09 字数 843 浏览 0 评论 0原文

我有一个包含 M1M2M3 列的数据库。这些M值对应于通过每种方法获得的值。我现在的想法是为他们每个人制作一个排名列。对于M1M2,排名将从最高值到最低值,而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

调整排名:

我使用了代码,但在我正在处理的情况下,我的排名如下所示: 输入图片此处描述

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一抹淡然 2025-01-19 09:37:09

使用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

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
香草可樂 2025-01-19 09:37:09

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

What I would do to achieve this result would be to transform each of the df columns into factors, and then convert them into numeric again. This could be accomplished in basic R, but for simplicity I report the tidyverse code:

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))))
☆獨立☆ 2025-01-19 09:37:09

另一种可能的解决方案基于 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

Another possible solution, based on 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
陌伤浅笑 2025-01-19 09:37:09
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)))
)]
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)))
)]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文