如何调整pivot_wider结果,按玩家个人比赛场次排列网球赛事数据?
解决方案:重构网球赛事数据格式
完整代码实现
library(tidyverse) # 原始数据 data <- structure(list(player = c("Bob", "Luc", "Bob", "Carl", "Alex", "John", "Alex", "Mike", "Carl", "Alex"), game = c(1, 1, 3, 3, 4, 4, 6, 6, 8, 8), rank = c(100, 110, 110, 120, 100, 90, 110, 80, 110, 120)), class = "data.frame", row.names = c(NA, -10L)) # 数据转换流程 result <- data %>% # 给原始非连续game分配连续的全局序号(1到5) mutate(global_game = dense_rank(game)) %>% # 按玩家分组,生成每个玩家的参赛顺序号(1、2、3...) group_by(player) %>% mutate(player_game = row_number()) %>% ungroup() %>% # 转换为宽格式,以player_game为行索引 pivot_wider(names_from = player, values_from = rank) %>% # 生成连续的game序列并关联,确保覆盖所有1-5的行 right_join(tibble(game = 1:max(.$global_game)), by = c("player_game" = "game")) %>% # 调整列名和顺序,将game列放在首位 select(game = player_game, Bob, Luc, Carl, Alex, John, Mike) # 输出结果 result
执行结果
# A tibble: 5 x 7 game Bob Luc Carl Alex John Mike <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 1 100 110 120 100 90 80 2 2 110 NA 110 110 NA NA 3 3 NA NA NA 120 NA NA 4 4 NA NA NA NA NA NA 5 5 NA NA NA NA NA NA
步骤解释
- 生成全局连续game序号:使用
dense_rank(game)将原始非连续的game值(1、3、4、6、8)转换为连续的1-5序号,对应最终结果的game列。 - 标记玩家参赛顺序:按
player分组后用row_number(),给每个玩家的比赛按原始game的时间顺序分配个人参赛序号(比如Bob的两场比赛对应序号1、2,Alex的三场对应1、2、3)。 - 转换为宽格式:通过
pivot_wider将数据转为玩家为列、个人参赛序号为行的结构,此时每个玩家的rank会对应到他们自己的参赛序号行。 - 补全连续game行:生成包含1-5连续序号的基础表,用
right_join关联到宽格式数据,确保所有连续game行都被保留,未填充的位置自动设为NA。 - 整理列结构:重命名列并调整顺序,让game列处于首位,玩家列按原始数据中的出现顺序排列。
内容的提问来源于stack exchange,提问作者Camillionnaire
相关产品推荐
相关产品推荐

