如何用R dplyr转换排名表:按选手整理各赛事排名
问题描述
现有如下R语言tibble数据表:
tibble( rank = c(1, 2, 3), race_A = c("John", "Nick", "George"), race_B = c("Jay", "Nick", "John"), race_C = c("Jay", "Jack", "Robbie") )
运行后得到的数据表为:
# A tibble: 3 × 4 rank race_A race_B race_C <dbl> <chr> <chr> <chr> 1 1 John Jay Jay 2 2 Nick Nick Jack 3 3 George John Robbie
需要使用R的dplyr包将其转换为如下结构的数据表(注:目标表中racer列类型应为字符型,原示例标注有误):
# A tibble: 7 × 4 racer race_A race_B race_C <chr> <dbl> <dbl> <dbl> 1 John 1 3 NA 2 Nick 2 2 NA 3 George 3 NA NA 4 Jay NA 1 1 5 John NA 3 NA 6 Jack NA NA 2 7 Robbie NA NA 3
解决方案
可以通过数据重塑+匹配填充的方式实现,具体代码如下:
library(dplyr) library(tidyr) # 该包与dplyr同属tidyverse系列,需配合使用 # 定义原始数据 original_df <- tibble( rank = c(1, 2, 3), race_A = c("John", "Nick", "George"), race_B = c("Jay", "Nick", "John"), race_C = c("Jay", "Jack", "Robbie") ) # 执行转换 result_df <- original_df %>% # 1. 将各赛事列转为长格式,记录选手与对应赛事的排名 pivot_longer(cols = starts_with("race_"), names_to = "race", values_to = "racer") %>% # 2. 转回宽格式,以选手为行,各赛事列填充对应排名,无排名则补NA pivot_wider(names_from = "race", values_from = "rank") %>% # 3. 按示例顺序排序(可选,若无需严格匹配顺序可删除) arrange(match(racer, c("John", "Nick", "George", "Jay", "Jack", "Robbie"))) print(result_df)
步骤说明
- pivot_longer:把
race_A/race_B/race_C拆分出赛事名称和选手两列,保留对应的排名,让每条记录对应「选手-赛事-排名」的关系。 - pivot_wider:以选手为行维度,将不同赛事转为列,用对应的排名填充单元格,没有参赛记录的位置自动补
NA。 - arrange:按照示例输出的选手顺序排序,若不需要严格匹配示例顺序,可直接去掉这一步。
内容的提问来源于stack exchange,提问作者GeorgeM
相关产品推荐
相关产品推荐

