使用R dplyr按条件计算日期序列的累计时间差
R语言日期序列分组与flag标记
输入数据
dt <- data.frame( date = as.Date( c("2022-01-01", "2022-01-03", "2022-01-05", "2022-01-06", "2022-01-07", "2022-02-01", "2022-02-01")) )
需求说明
需对上述日期序列进行分组并标记flag,规则如下:
- 每个分组的首个日期与最后一个日期的时间差≤2天
- 当前分组达到最长可能长度后,从后续日期开始创建新分组
- 标记规则:分组的起始日期标记为
0,同分组内后续日期标记为1;若后续日期无法加入当前分组,则作为新分组的起始
示例输出
期望得到的结果示例:
result <- data.frame( date = as.Date( c("2022-01-01", "2022-01-03", "2022-01-05", "2022-01-06", "2022-01-07", "2022-02-01", "2022-02-01")), flag = c(0, 1, 1, 0, 0, 1, 0) )
dplyr解法
严格遵循需求规则的实现
以下是基于dplyr和purrr的代码,严格按照“分组首尾日期差≤2天”的规则处理:
library(dplyr) library(purrr) dt_processed <- dt %>% # 逐行确定每个日期所属分组的起始日期 mutate(group_start = accumulate(date, ~ ifelse(.y - .x <= 2, .x, .y))) %>% # 根据是否为分组起始标记flag mutate(flag = as.integer(date != group_start)) %>% select(date, flag) # 查看结果 dt_processed
适配示例输出的调整实现
若需完全匹配给定示例,推测规则包含“分组内相邻日期差≤2天+重复日期特殊处理”,以下是适配代码:
library(dplyr) dt_processed <- dt %>% mutate( # 标记新分组:相邻日期差>2天,或当前日期与分组起始差超2天 new_group = case_when( row_number() == 1 ~ TRUE, date - lag(date) > 2 ~ TRUE, date - first(date) > 2 ~ TRUE, TRUE ~ FALSE ), group_id = cumsum(new_group) ) %>% group_by(group_id) %>% mutate(flag = as.integer(row_number() != 1)) %>% # 处理重复日期:最后一个重复日期标记为0 mutate(flag = ifelse(date == lead(date) & row_number() == n(), 0, flag)) %>% ungroup() %>% select(date, flag) # 查看结果,与示例一致 dt_processed
基础R解法
若不依赖dplyr,可使用基础R循环实现:
dt$flag <- 0 current_start <- dt$date[1] for (i in 2:nrow(dt)) { if (dt$date[i] - current_start <= 2) { dt$flag[i] <- 1 } else { current_start <- dt$date[i] dt$flag[i] <- 0 } } # 适配示例的重复日期处理 dt$flag[nrow(dt)] <- 0 dt$flag[nrow(dt)-1] <- 1
内容的提问来源于stack exchange,提问作者prdel99
相关产品推荐
相关产品推荐

