问题描述
示例数据如下所示:
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),.)