在 R 的数据框中添加多个排名列

Adding multiple ranking columns in a dataframe in R

我有以下 df:

id city uf home money work
34  LA  RJ  10     2     2   
33  BA  TY  7      3     65
32  NY  BN  4      5     4
12  SP  SD  3      9     7
14  FR  DE  1      8     9
17  BL  DE  5      10    8

期望的测距仪:

id city uf home  rank_home  money    rank_money   work   rank_work
34  LA  RJ  10    1          2         6           2       6
33  BA  TY  7     2          3         5           65      1
32  NY  BN  4     4          5         4           4       5
12  SP  SD  3     5          9         2           7       4
14  FR  DE  1     6          8         3           9       2
17  BL  DE  5     3          10        1           8       3

我知道这是可能的: dat$rank_home <- rank(dat$home)

但我想要一个更简洁的多列代码!

谢谢!!

我们可以循环 across 列 'home' 到 'work',应用 rank,同时通过在 .names 中添加前缀来创建新列,以及可能select保持秩序

library(dplyr)
df1 <- df %>% 
   mutate(across(home:work, ~ rank(-.), .names = "rank_{.col}"))

或者可以在循环中执行此操作,通过指定 .after.before 可以更灵活地将列放置在特定位置。请注意,我们使用了复合赋值运算符(magrittr 中的%<>%)来就地赋值

library(magrittr)
library(stringr)
for(nm in names(df)[4:6]) df %<>%
     mutate(!!str_c("rank_", nm) := rank(-.data[[nm]]), .after = all_of(nm))

-输出

df
  id city uf home rank_home money rank_money work rank_work
1 34   LA RJ   10         1     2          6    2         6
2 33   BA TY    7         2     3          5   65         1
3 32   NY BN    4         4     5          4    4         5
4 12   SP SD    3         5     9          2    7         4
5 14   FR DE    1         6     8          3    9         2
6 17   BL DE    5         3    10          1    8         3

注意:如果列有关系,则默认使用的方法是 "average"。因此,ties.method 也可以是 rank 中有关系的参数。

数据

df <- structure(list(id = c(34L, 33L, 32L, 12L, 14L, 17L), city = c("LA", 
"BA", "NY", "SP", "FR", "BL"), uf = c("RJ", "TY", "BN", "SD", 
"DE", "DE"), home = c(10L, 7L, 4L, 3L, 1L, 5L), money = c(2L, 
3L, 5L, 9L, 8L, 10L), work = c(2L, 65L, 4L, 7L, 9L, 8L)), 
class = "data.frame", row.names = c(NA, 
-6L))

基本 R 选项

cbind(
    df,
    setNames(
        lapply(-df[-(1:3)], rank),
        paste0("rank_", names(df)[-(1:3)])
    )
)

给予

  id city uf home money work rank_home rank_money rank_work
1 34   LA RJ   10     2    2         1          6         6
2 33   BA TY    7     3   65         2          5         1
3 32   NY BN    4     5    4         4          4         5
4 12   SP SD    3     9    7         5          2         4
5 14   FR DE    1     8    9         6          3         2
6 17   BL DE    5    10    8         3          1         3

data.table

中的一个可选方法
library(data.table)
new <- paste0("rank_",names(dt[,4:6]))
dt[,(new):=lapply(-.SD,frankv),.SDcols=4:6]