r - 使用 dplyr 获取每列的排名

标签 r dplyr

我正在尝试获取数据框中每一列的排名。

理想的输出(以 mtcars 为例)如下所示,但每列都填写了排名:

                   mpg cyl  disp  hp drat    wt  qsec vs am gear carb mpg_rank cyl_rank disp_rank ...
Mazda RX4         21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag     21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
Datsun 710        22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive    21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
Hornet Sportabout 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
....

我可以为每一列生成一个排名,但我无法获得上述格式的输出......这就是我正在努力的地方。

cols <- colnames(mtcars)

get_rank <- function(col){
  
  df %>% mutate(rank=rank(.data[[col]]))
}

lapply(cols, get_rank)

最佳答案

我们可以使用across - 循环数字列,获取排名并通过在.names中添加后缀来创建新的列名称

library(dplyr)
out <- mtcars %>% 
   mutate(across(where(is.numeric), rank, .names = "{.col}_rank"))

-输出

> head(out, 2)
              mpg cyl disp  hp drat    wt  qsec vs am gear carb mpg_rank cyl_rank disp_rank hp_rank drat_rank wt_rank qsec_rank vs_rank
Mazda RX4      21   6  160 110  3.9 2.620 16.46  0  1    4    4     19.5       15      13.5      13      21.5       9       6.0     9.5
Mazda RX4 Wag  21   6  160 110  3.9 2.875 17.02  0  1    4    4     19.5       15      13.5      13      21.5      12      10.5     9.5
              am_rank gear_rank carb_rank
Mazda RX4          26      21.5      25.5
Mazda RX4 Wag      26      21.5      25.5

默认情况下,如果存在平局,则排名可能取平均值

rank(x, na.last = TRUE, ties.method = c("average", "first", "last", "random", "max", "min"))

因此,最好指定 ties.method 或使用 dense_rank

out <- mtcars %>% 
   mutate(across(where(is.numeric), dense_rank, .names = "{.col}_rank"))

-输出

> head(out, 2)
              mpg cyl disp  hp drat    wt  qsec vs am gear carb mpg_rank cyl_rank disp_rank hp_rank drat_rank wt_rank qsec_rank vs_rank
Mazda RX4      21   6  160 110  3.9 2.620 16.46  0  1    4    4       16        2        13      11        16       9         6       1
Mazda RX4 Wag  21   6  160 110  3.9 2.875 17.02  0  1    4    4       16        2        13      11        16      12        10       1
              am_rank gear_rank carb_rank
Mazda RX4           2         2         4
Mazda RX4 Wag       2         2         4

关于OP的函数,它使用df作为输入数据集,该数据集不是函数的参数,默认情况下dfbase R<中的函数。此外,rank= 返回每个列名称为rank。该函数可以修改为

cols <- colnames(mtcars)

get_rank <- function(data, col){
  
  data %>% 
   transmute(!! stringr::str_c(col, "_rank") :=rank(.data[[col]]))
}

lapply(cols, get_rank, data = mtcars) %>%
   bind_cols(mtcars, .)

关于r - 使用 dplyr 获取每列的排名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71385178/

相关文章:

r - 根据另一列中的数据绘制一列中值的总和

r - 具有多个 (x,y) 对的数据框的高格式

r - 为什么更改对比度类型会更改 R lm 摘要中的行标签?

r - 合并 R 保留数据集的所有行

r - PostgreSQL + dplyr : loading bigint as a text column

在每个分位数内随机分配大小相等的子组

r - 使用 "[]"对 tibble 进行子集化会产生 "object not found"错误

r - 如何导出列分割的子集?

r - 开发引用 n-1 行的更有效的 for 循环

r - 如何在 rmarkdown 中正确对齐数学方程?