如何跨年度按「7月1日起的周」等固定月日周聚合日期?
跨年月日固定7天区间分组问题
数据
处理2019-2022年的日期数据,生成代码如下:
library(tidyverse) library(lubridate) set.seed(123) df <- tibble( date = sample( seq(as.Date('2019/01/01'), as.Date('2022/09/01'), by = "day"), size = 100, replace = T))
需求
创建新变量,将所有日期归到统一的月日区间对应的周分组:以固定月日为周起始,每7天一组,跨年份的相同月日区间需对应同一个分组标签,不考虑日期实际的星期几或年度周数。
示例规则:
- 2019-07-03、2021-07-03~07均对应「July 01」
- 2021-07-08~14对应「July 08」
- 2021-07-15~21、2022-07-15对应「July 15」
尝试过的无效方法
使用lubridate::floor_date()时,返回的是对应年份的基准日期,无法实现跨年月日统一分组:
df %>% mutate( date_month_week = lubridate::floor_date(date, unit = "week", week_start = 7), date_month_week = format(as.Date(date_month_week), "%m-%d")) %>% arrange(desc(date_month_week)) %>% distinct(date_month_week)
得到的结果包含不同年份的非统一区间:
# A tibble: 77 × 1 date_month_week <chr> 1 12-20 2 12-15 3 12-12 4 12-08 5 12-06 6 12-01 7 11-28 8 11-24 9 11-22 10 11-21
解决方案
核心思路是:将所有日期的月日映射到同一个基准年(选闰年如2020年,避免2月29日格式错误),通过当年天数计算所属的7天区间起始,最后统一格式输出分组标签。
代码实现:
df %>% mutate( # 提取月日,转换为2020年的基准日期 fixed_date = as.Date(paste0("2020-", format(date, "%m-%d"))), # 计算该基准日期所在的7天区间起始(从1月1日开始每7天一组) week_start = as.Date(((yday(fixed_date) - 1) %/% 7) * 7 + 1, origin = "2019-12-31"), # 格式化为「Month DD」的分组标签 week_label = format(week_start, "%B %d") ) %>% # 按日期排序查看结果 arrange(date) %>% select(date, week_label)
代码说明
- 映射基准年:把不同年份的相同月日转换到2020年,确保所有日期的月日区间计算基准一致。
- 计算区间起始:通过
yday()获取基准日期在当年的天数,用整数除法%/%计算所属的7天组,再转换回日期得到区间起始。 - 格式化标签:将起始日期转换为英文月份加日期的格式,实现跨年份统一分组。
内容的提问来源于stack exchange,提问作者Cameron
相关产品推荐
相关产品推荐

