在dplyr中使用RLE分组后保留连胜区间的首尾日期
为连胜区间添加起止日期的解决方案
问题场景
现有一份按时间排序的比赛结果数据集,包含队伍、对手、日期、胜负结果字段。已实现按队伍+对手分组统计最大连胜场次,但需要进一步获取对应连胜区间的首次日期和末次日期。原代码中使用first()/last()会针对整个分组计算,无法定位到具体连胜区间。
解决方案代码
library(tidyverse) # 示例数据集 test <- data.frame(date = c(1:10), team = c(rep(c("red", "blue"),5)), opponent = c("black", "white", "black", "white", "white", "black", "white", "white", "black", "white"), result = c(1,1,1,0,0,1,0,0,1,1)) # 处理逻辑:先标记连胜区间,再统计区间信息 test %>% group_by(team, opponent) %>% # 生成连续胜负段的分组ID,仅为胜场分配有效ID mutate( run_id = with(rle(result), rep(seq_along(lengths), lengths)), win_run_id = ifelse(result == 1, run_id, NA) ) %>% # 按胜场区间分组统计 group_by(team, opponent, win_run_id, .drop = FALSE) %>% summarise( consec_wins = sum(result), first_date = first(date), last_date = last(date), .groups = "drop_last" ) %>% # 筛选有效胜场区间,并保留每个组合的最大连胜记录 filter(consec_wins > 0) %>% group_by(team, opponent) %>% filter(consec_wins == max(consec_wins)) %>% ungroup() %>% select(team, opponent, consec_wins, first_date, last_date)
代码说明
- 标记连胜区间:用
rle()识别连续的胜负结果,生成run_id标记每个连续段;仅为胜场保留win_run_id,负场设为NA以便后续过滤。 - 区间统计:按
队伍+对手+win_run_id分组,统计该区间的连胜场次、首次和末次日期。 - 筛选最大连胜:过滤无胜场的记录后,保留每个
队伍+对手组合中连胜场次最多的区间(若有多个相同最大场次的区间,会全部保留)。
输出示例
# A tibble: 4 × 5 team opponent consec_wins first_date last_date <chr> <chr> <dbl> <int> <int> 1 blue black 1 6 6 2 blue white 1 2 2 3 blue white 1 10 10 4 red black 3 1 9
内容的提问来源于stack exchange,提问作者Jeff Henderson
相关产品推荐
相关产品推荐

