对数据框中选定的多列进行排名,然后将排名数据添加为新列

问题描述

示例数据如下所示:

players <- seq(1:10)
mean_K <- round(runif(10,1,10),2)
mean_D <- round(runif(10,2)
mean_A <- round(runif(10,2)
d <- cbind(players,mean_K,mean_A,mean_D)
d <- as_tibble(d)
d

输出

# A tibble: 10 x 4
   players mean_K mean_A mean_D
     <dbl>  <dbl>  <dbl>  <dbl>
 1       1   3.58   9.21   3.4 
 2       2   3.8    0.49   1.33
 3       3   2.47   2.29   1.72
 4       4   1.52   7.25   6.11
 5       5   8.73   3.98   8.08
 6       6   8.08   9.77   3.88
 7       7   3.97   4.52   9.93
 8       8   2.84   6.83   9.57
 9       9   3.87   0.35   5.32
10      10   2.82   3.8    3.09

我想做的是同时对选定的列进行排名,我尝试使用 apply :

apply(d[,2:4],2,rank)

输出

      mean_K mean_A mean_D
 [1,]      5      9      4
 [2,]      6      2      1
 [3,]      2      3      2
 [4,]      1      8      7
 [5,]     10      5      8
 [6,]      9     10      5
 [7,]      8      6     10
 [8,]      4      7      9
 [9,]      7      1      6
[10,]      3      4      3

但是后来我被卡住了,如何将所有新的排名列添加到数据框 d 中?我想知道是否可以使用 dplyr 管道 %>% 来做到这一点?

我想要的输出可能如下所示:

   players mean_K mean_K_ranking mean_D mean_D_ranking mean_A mean_A_ranking
1        1   3.58              5   3.40              4   9.21              9
2        2   3.80              6   1.33              1   0.49              2
3        3   2.47              2   1.72              2   2.29              3
4        4   1.52              1   6.11              7   7.25              8
5        5   8.73             10   8.08              8   3.98              5
6        6   8.08              9   3.88              5   9.77             10
7        7   3.97              8   9.93             10   4.52              6
8        8   2.84              4   9.57              9   6.83              7
9        9   3.87              7   5.32              6   0.35              1
10      10   2.82              3   3.09              3   3.80              4

解决方法

我们可以分配。在这里,我们使用 lapply 循环遍历列(如果 type 中存在一些差异,则 lapply 保留它,而 apply 转换为 matrix 和那些将只有一种类型)

lst1 <- lapply(d[2:4],rank)
d[paste0(names(lst1),"_ranking")] <- lst1

或者使用 tidyverse

library(dplyr)
d <- d %>%
     mutate(across(starts_with('mean'),rank,.names = "{.col}_ranking"))

或者可以使用 imap 中的 purrr 按照预期对列进行排序

library(purrr)
library(stringr)
d %>% 
    select(starts_with('mean_')) %>% 
    imap_dfc(~ tibble(!! .y := .x,!!str_c(.y,'_ranking') := rank(.x))) %>% 
    bind_cols(d %>% 
               select(players),.)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...