如何在R中获取选手列的唯一组合并按正确顺序汇总得分?
问题与解决方法
问题背景
我有一张体育比赛结果表,p1和p2列存储选手信息,p1.score和p2.score列存储对应选手的单场得分,数据如下:
| p1 | p2 | p1.score | p2.score |
|---|---|---|---|
| Trevor | Patrick | 5 | 2 |
| Patrick | Trevor | 3 | 7 |
对应的R数据构造代码:
library(dplyr) matches <- tibble(p1=c("Trevor","Patrick"), p2=c("Patrick","Trevor"), p1.score=c(5,3), p2.score=c(2,7))
需要按p1和p2的唯一组合分组,正确累加每个选手的得分——比如Trevor和Patrick的累计得分应该是12和5。
尝试用dplyr的group_by结合pmin和pmax获取唯一组合,再用summarize汇总得分,但结果错误:
matches %>% group_by(a = pmin(p1,p2), b = pmax(p1,p2)) %>% summarize(a.wins = sum(p1.score), b.wins = sum(p2.score)) # 输出结果: # A tibble: 1 × 4 # Groups: a [1] a b a.wins b.wins <chr> <chr> <dbl> <dbl> 1 Patrick Trevor 8 9
错误原因是直接累加p1.score和p2.score时,没有对应分组后a/b与选手实际得分的关系。
正确解法
方法一:分组内匹配选手得分
对每组内的每一行,判断当前行的p1是分组后的第一个选手还是第二个,再把对应得分加到正确的累计项中:
matches %>% group_by( player1 = pmin(p1, p2), player2 = pmax(p1, p2) ) %>% summarize( player1_total = sum(ifelse(p1 == player1, p1.score, p2.score)), player2_total = sum(ifelse(p1 == player2, p1.score, p2.score)) )
运行结果:
# A tibble: 1 × 4 player1 player2 player1_total player2_total <chr> <chr> <dbl> <dbl> 1 Patrick Trevor 5 12
方法二:转换为长格式后汇总
先将宽格式数据转为长格式,让每个选手的得分单独成一行,再按选手分组求和,这种方式更直观灵活:
library(tidyr) # 需要加载tidyr包用于pivot_longer matches %>% pivot_longer( cols = c(p1, p2), names_to = "player_position", values_to = "player" ) %>% mutate( score = case_when( player_position == "p1" ~ p1.score, player_position == "p2" ~ p2.score ) ) %>% group_by(player) %>% summarize(total_score = sum(score))
运行结果:
# A tibble: 2 × 2 player total_score <chr> <dbl> 1 Patrick 5 2 Trevor 12
内容的提问来源于stack exchange,提问作者Trevor Greissinger
相关产品推荐
相关产品推荐

