按公共日期合并两个数据帧:提取匹配行前后指定行及事件标记
两个数据框按行偏移规则合并及事件标记方案
基于R语言tidyverse生态工具实现,全程以行号作为位置索引做偏移匹配,避免日期缺测、断档导致的范围计算错误,完全对齐需求规则。
核心逻辑
- 预处理阶段统一两个表的日期格式,为时间连续的流量表添加连续行号作为位置索引
- 为事件表的每条记录匹配其在流量表中的锚点位置,计算每个事件需要覆盖的行范围:锚点位置前2行 ~ 锚点位置+length-1行
- 逐事件提取流量表对应范围的记录,绑定统一事件编号,仅锚点行保留length字段值,其余关联行的length填NA
- 整理字段顺序得到最终结果
完整可运行代码
library(tidyverse) # 1. 基础数据预处理 df1 <- df1 %>% mutate(datetime = as.Date(datetime)) df2 <- df2 %>% mutate(datetime = as.Date(datetime)) %>% # 生成连续行号作为取数的位置依据 mutate(row_id = row_number()) # 2. 匹配每个事件在流量表的锚点位置,计算取数范围、分配事件编号 event_range <- df1 %>% left_join(df2 %>% select(datetime, anchor_row = row_id), by = "datetime") %>% mutate(`event#` = row_number()) %>% mutate( start_row = anchor_row - 2, end_row = anchor_row + (length - 1) ) # 3. 逐事件提取对应范围的流量数据,绑定事件属性 result <- map_dfr( 1:nrow(event_range), function(i) { current_event <- event_range[i, ] df2 %>% filter(row_id >= current_event$start_row, row_id <= current_event$end_row) %>% mutate( `event#` = current_event$`event#`, # 仅事件锚点行保留length值,其余行填充NA length = ifelse(datetime == current_event$datetime, current_event$length, NA_real_), EventDatesNancy = datetime ) } ) %>% # 按需求调整输出字段顺序 select(EventDatesNancy, length, q, `event#`)
结果说明
- 输出字段顺序为
EventDatesNancy、length、q、event#,和需求给出的期望样例完全对齐,每个事件块内的行共享同一个event# - 若事件锚点靠近流量表头部/尾部,计算出的行范围超出表边界时,代码会自动截断到表的首尾行,不会抛出错误
- 若不同事件的覆盖范围存在重叠,重叠记录会分别归属到对应事件编号下,若需要单条记录仅归属一个事件,可根据业务优先级加去重逻辑调整
内容的提问来源于stack exchange,提问作者H. Dierker
相关产品推荐
相关产品推荐

