使用R语言dplyr提取赛事日期范围内的周一并标记周次
问题场景
我们有ATP网球赛事的举办时间数据,结构如下:
| Tournament | Date Range |
|---|---|
| Australian Open | 20.01.2020 - 02.02.2020 |
需要完成两个核心需求:
- 提取日期范围内的所有周一
- 为每个周一标记它属于赛事的第1周还是第2周(赛事淘汰制下第二周参赛选手水平更高)
期望输出格式:
| Tournament | Date | Number of week |
|---|---|---|
| Australian Open | 2020-01-20 | 1 |
| Australian Open | 2020-01-27 | 2 |
解决思路与分步实现
1. 拆分日期范围并生成全量日期
首先将Date Range列拆分为开始、结束两个日期列,再把日期区间内的每一天展开:
library(dplyr) library(tidyr) library(lubridate) # 拆分日期范围为开始、结束列 tennis.orf.2020.2 <- tennis.orf.2020 %>% separate(`Date Range`, c("Start", "End"), sep = " - ") # 转换日期格式,生成区间内的所有天数 x <- tennis.orf.2020.2 %>% mutate(across(c(Start, End), as.Date, "%d.%m.%y")) %>% transmute(Tournament, date = map2(Start, End, seq, by = 'day')) %>% unnest(c(date))
2. 筛选周一
使用lubridate包的wday()函数筛选周一(默认规则:周日=1,周一=2,和SQL的DAYOFWEEK逻辑匹配):
x <- x %>% filter(wday(date) == 2)
3. 标记赛事周次(解决核心问题)
之前用count()得到的周次全为1,是因为count()仅统计分组数量,而非按顺序标记周次。我们可以按日期排序后,分组生成递增序号:
x <- x %>% arrange(date) %>% group_by(Tournament) %>% mutate(`Number of week` = row_number()) # 直接用row_number生成周次序号 ungroup()
完整优化代码
整合所有步骤,简化冗余操作:
library(dplyr) library(tidyr) library(lubridate) final_result <- tennis.orf.2020 %>% separate(`Date Range`, c("Start", "End"), sep = " - ") %>% mutate(across(c(Start, End), as.Date, "%d.%m.%y")) %>% transmute(Tournament, date = map2(Start, End, seq, by = 'day')) %>% unnest(c(date)) %>% filter(wday(date) == 2) %>% arrange(date) %>% group_by(Tournament) %>% mutate(`Number of week` = row_number()) %>% ungroup() # 查看最终结果 final_result
运行后即可得到符合要求的输出,row_number()会在分组内按日期顺序生成1、2...的周次标记。
内容的提问来源于stack exchange,提问作者vie2bgd
相关产品推荐
相关产品推荐

