R语言实现每位球员各轮次累计to par值计算
问题原因
原代码直接对整列调用cumsum()计算累计值时,没有按「球员、轮次」拆分计算单元,会把所有行从上到下连续累加,导致跨球员、跨轮次的数值被错误加总;如果同组内球洞顺序混乱,还会出现累加顺序不符合实际打球流程的问题。
修复方法
在计算累计值前,先通过group_by()按球员、轮次分组,再按球洞序号排序保证累加顺序正确,此时cumsum()会在每个独立分组内单独计算累计值,不会出现跨组串值的问题。
修复后的完整可运行代码如下:
# 提前加载依赖包,原代码缺省包加载步骤容易运行报错 library(tidyverse) load(url( "https://www.stat.osu.edu/~vqv/4194/data/masters2011-untidy.rda" )) rounds <- list(round1, round2, round3, round4) names(rounds) <- 1:4 all_rounds <- bind_rows(rounds, .id = 'round') scorecard <- all_rounds %>% pivot_longer(cols = '1':'18', names_to = 'hole', values_to = 'score') %>% mutate(round = as.integer(round), hole = as.integer(hole)) %>% select(player, round, hole, score) topar <- scorecard %>% left_join(course, by = "hole") %>% mutate(to_par = score - par) %>% # 按球员、轮次拆分独立计算组 group_by(player, round) %>% # 组内按球洞号升序排列,保证累加从1号洞到18号洞顺序正确 arrange(hole, .by_group = TRUE) %>% # 分组状态下计算累计to par,仅在当前组内累加 mutate(cumulative = cumsum(to_par)) %>% # 计算完成后解除分组,方便后续其他数据处理 ungroup()
结果校验
计算完成后可随机抽取单球员单轮次数据核验:
- 1号洞的累计to par值等于该洞单洞to par值
- N号洞(N>1)的累计to par值等于前N个洞的单洞to par值之和
- 18号洞的累计to par值等于该球员该轮总杆与该轮标准杆总杆数的差值,和赛事计分规则一致。
内容的提问来源于stack exchange,提问作者ShaneH
相关产品推荐
相关产品推荐

