如何按日期分组统计球队相较于上一场的新增球员数?
问题描述
我有如下结构的data.frame:
| 比赛日期 | 球队 | 球员 |
|---|---|---|
| 2020-09-12 | Liverpool | A |
| 2020-09-12 | Liverpool | B |
| 2020-09-12 | Liverpool | C |
| 2020-09-12 | Man Utd | D |
| 2020-09-12 | Man Utd | E |
| 2020-09-12 | Man Utd | F |
| 2020-09-12 | Arsenal | G |
| 2020-09-12 | Arsenal | H |
| 2020-09-12 | Arsenal | I |
| 2020-09-15 | Liverpool | A |
| 2020-09-15 | Liverpool | B |
| 2020-09-15 | Liverpool | C |
| 2020-09-15 | Man Utd | D |
| 2020-09-15 | Man Utd | E |
| 2020-09-15 | Man Utd | Q |
| 2020-09-15 | Arsenal | G |
| 2020-09-15 | Arsenal | O |
| 2020-09-15 | Arsenal | I |
| 2020-09-18 | Liverpool | A |
| 2020-09-18 | Liverpool | B |
| 2020-09-18 | Liverpool | C |
| 2020-09-18 | Man Utd | M |
| 2020-09-18 | Man Utd | H |
| 2020-09-18 | Man Utd | Q |
| 2020-09-18 | Arsenal | G |
| 2020-09-18 | Arsenal | H |
| 2020-09-18 | Arsenal | I |
需要统计每支球队在每个比赛日中,相较于上一个比赛日新增的球员数量,规则为:若球员在第一场出现、缺席第二场后又出现在第三场,需算作第三场的新增球员。
期望输出如下:
| 比赛日期 | 球队 | 新增球员数 |
|---|---|---|
| 2020-09-15 | Liverpool | 0 |
| 2020-09-15 | Man Utd | 1 |
| 2020-09-15 | Arsenal | 1 |
| 2020-09-18 | Liverpool | 0 |
| 2020-09-18 | Man Utd | 2 |
| 2020-09-18 | Arsenal | 1 |
请问是否有简洁的实现方式?
实现方案
可以用tidyverse工具链实现,这里提供两种简洁思路:
方法一:基于球员历史出现日期对比
核心逻辑是标记每个球员上一次出场的比赛日,再对比该日期是否为当前比赛日的前一个比赛日,统计不符合的球员数量:
library(tidyverse) # 假设原始数据框名为df df %>% group_by(球队, 球员) %>% mutate(上一次比赛日 = lag(比赛日期)) %>% ungroup() %>% group_by(比赛日期, 球队) %>% summarise(新增球员数 = sum(is.na(上一次比赛日) | 上一次比赛日 != lag(比赛日期, default = first(比赛日期))), .groups = "drop") %>% filter(比赛日期 != first(比赛日期))
方法二:基于比赛日球员列表差集
按球队分组后,提取每个比赛日的球员列表,直接和上一个比赛日的列表做差集统计数量,逻辑更直观:
library(tidyverse) df %>% group_by(球队, 比赛日期) %>% summarise(球员列表 = list(球员), .groups = "drop") %>% group_by(球队) %>% mutate(上一次球员列表 = lag(球员列表), 新增球员数 = map2_int(球员列表, 上一次球员列表, ~length(setdiff(.x, .y)))) %>% filter(!is.na(上一次球员列表)) %>% select(比赛日期, 球队, 新增球员数)
两种方法都能得到符合要求的输出,方法一效率更高适合大数据量,方法二逻辑更易理解。
内容的提问来源于stack exchange,提问作者Delopera
相关产品推荐
相关产品推荐

