如何按组计算相邻行End_Date与Start_Date的天数差?
按ID分组计算相邻行日期天数差的解决方案
需求说明:按ID分组,计算每组内下一行的Start_Date与上一行的End_Date的天数差,将结果存入新列Days_Difference,每组第一行该列值为NA。
输入数据示例
Start_Date End_Date ID 2014-05-09 2015-05-08 01 2015-05-09 2016-05-08 01 2016-05-11 2017-05-10 01 2017-05-11 2018-05-10 01 2016-08-29 2017-08-28 02 2017-08-29 2018-08-28 02
期望输出结果
Start_Date End_Date ID Days_Difference 2014-05-09 2015-05-08 01 NA 2015-05-09 2016-05-08 01 01 2016-05-11 2017-05-10 01 03 2017-05-11 2018-05-10 01 01 2016-08-29 2017-08-28 02 NA 2017-08-29 2018-08-28 02 01
1. tidyverse 解决方案
使用dplyr的分组和滞后函数实现,步骤清晰易读:
- 将日期列转换为日期格式(确保时差计算有效);
- 按
ID分组,用lag()获取上一行的End_Date; - 计算当前行
Start_Date与上一行End_Date的差值,第一行自动返回NA。
library(tidyverse) # 转换日期格式并计算天数差 df <- df %>% mutate(across(c(Start_Date, End_Date), as.Date)) %>% group_by(ID) %>% mutate(Days_Difference = as.integer(Start_Date - lag(End_Date))) %>% ungroup() # 查看结果 print(df)
2. data.table 解决方案
利用data.table的高效分组和移位函数,适合处理大规模数据集:
- 转换为
data.table格式并处理日期列; - 按
ID分组,用shift()获取上一行的End_Date; - 计算时差并赋值给新列。
library(data.table) # 转换为data.table并处理日期 setDT(df) df[, c("Start_Date", "End_Date") := lapply(.SD, as.Date), .SDcols = c("Start_Date", "End_Date")] df[, Days_Difference := as.integer(Start_Date - shift(End_Date)), by = ID] # 查看结果 print(df)
3. base R 解决方案
无需额外依赖包,通过拆分-处理-合并的流程实现:
- 先转换日期列格式;
- 按
ID拆分数据框; - 对每个子集计算相邻行的时差;
- 合并所有子集并重置行名。
# 转换日期格式 df$Start_Date <- as.Date(df$Start_Date) df$End_Date <- as.Date(df$End_Date) # 按ID拆分并处理每个子集 df_list <- split(df, df$ID) df_list <- lapply(df_list, function(x) { x$Days_Difference <- c(NA, x$Start_Date[-1] - x$End_Date[-nrow(x)]) x }) # 合并结果 df_result <- do.call(rbind, df_list) rownames(df_result) <- NULL # 查看结果 print(df_result)
内容的提问来源于stack exchange,提问作者emp88
相关产品推荐
相关产品推荐

