如何用nest_by()、across()和summarise()替代已废弃的do()实现按周展开日期区间
用nest_by()、summarise()替代废弃的do()实现按周拆分时间段需求
你提到的do()函数确实已经被dplyr标记为废弃,官方推荐用nest_by()结合summarise()来实现这类逐组的行展开操作,这和你想要的nest_by()、across()、summarise()的方向一致(across()更多用于多列批量操作,你的场景里单组的start/end用nest_by()+summarise()就足够简洁)。
先回顾你的原始数据集:
library(tidyverse) library(lubridate) # 构建原始数据集 start_dates = ymd_hms(c("2019-05-08 00:00:00", "2020-01-17 00:00:00", "2020-03-03 00:00:00", "2020-05-28 00:00:00", "2020-12-10 00:00:00", "2021-05-07 00:00:00", "2022-01-04 00:00:00"), tz = "UTC") end_dates = ymd_hms(c( "2019-10-24 00:00:00", "2020-03-03 00:00:00", "2020-05-28 00:00:00", "2020-12-10 00:00:00", "2021-05-07 00:00:00", "2022-01-04 00:00:00", "2022-01-19 00:00:00"), tz = "UTC") df1 = data.frame(studying = paste0("period",seq(1:7),sep = ""),start_dates,end_dates)
官方推荐的替代实现
下面是用nest_by()+summarise()完成需求的代码,完全替代你之前的do()写法:
df1 %>% # 按分组字段和日期字段嵌套,生成行级分组的tibble nest_by(studying, start_dates, end_dates) %>% # 逐组生成周序列,summarise自动将序列展开为多行 summarise(week = seq(start_dates, end_dates, by = "1 week")) %>% # 取消分组,得到扁平的结果dataframe ungroup()
代码解释
nest_by(studying, start_dates, end_dates):和group_by()类似,但会把每个分组的剩余数据打包成一个行级的tibble,这样我们可以对每个组的start_dates和end_dates单独处理。summarise(week = seq(...)):在每个分组内,用seq()生成从起始日期到结束日期的周间隔序列,summarise会自动把这个向量展开成多行,同时保留studying分组标识。ungroup():最后取消分组结构,得到和你之前用do()、map2()完全一致的结果格式。
如果后续有多个类似的日期列需要批量处理,你可以结合across()来选择列,但在当前场景下,上面的写法已经足够简洁高效,完全符合官方的替代方案要求。
内容的提问来源于stack exchange,提问作者Dasr
相关产品推荐
相关产品推荐

