R语言用lubridate和slice函数计算分组第二行与末行的日期差
实现代码及说明
首先加载所需依赖包:
library(dplyr) library(lubridate)
完整处理逻辑如下:
# 构造原始数据 data<- data.frame(pid= c(1, 1, 1,1, 2, 2, 2, 3, 3, 3,3 ,3), day = c("25/07/2018", "19/10/2018", "17/01/2019", "19/03/2019", "10/09/2018","29/11/2018", "26/03/2019", "17/06/2016", "25/04/2018", "17/07/2018","05/04/2019", "09/02/2021"), catt=c(1,1,2,1,1,1,2,2,2,1,1,2)) # 数据处理 result <- data %>% # 转换文本日期为日期格式,适配原数据 日/月/年 的结构 mutate(day = dmy(day)) %>% # 按pid分组 group_by(pid) %>% # 仅在组内最后一行输出差值,其余行为空 mutate( # 计算逻辑:最后一行日期减第二行日期,天数除以30得到月度差 difference = ifelse( row_number() == n(), as.numeric(difftime(last(day), nth(day, 2), units = "days")) / 30, NA_real_ ) # 如果需要打印时NA显示为空,可取消注释下行代码 # ,difference = ifelse(is.na(difference), "", as.character(round(difference, 4))) ) %>% ungroup() # 查看结果 print(result, n = Inf)
逻辑说明
- 用lubridate的
dmy()函数自动解析文本格式的日期,无需手动指定每个日期值,适配大批量数据处理 - 分组后通过
nth(day, 2)取每个分组的第二行日期,last(day)取每个分组最后一行日期,和你原手动计算的逻辑完全对齐 - 通过
row_number() == n()判断当前行是否为分组最后一行,仅在最后一行写入计算结果,其余行留空,完全匹配你要的输出格式
注:你给出的样例输出中的数值存在笔误,按你提供的日期计算:pid1的第二行到最后一行差151天,月度差约为5.03;pid2的第二行到最后一行差117天,月度差约为3.9;pid3的第二行到最后一行差1021天,月度差约为34.03,代码计算结果符合实际日期差值逻辑。
内容的提问来源于stack exchange,提问作者berehan
相关产品推荐
相关产品推荐

