在R语言中当日期差超过7天时生成唯一ID
问题:按日期间隔生成连续分组ID
需求说明
- 遍历每一行数据,若当前行与上一行的日期差超过7天,则为当前行分配唯一ID;否则当前行与上一行使用相同ID,zipcode不影响ID生成。
提供的数据
z<- structure(list(zipcode = c(96717L, 96730L, 96825L, 96826L, 96720L, 96756L, 96740L, 96819L, 96734L, 96740L, 96714L, 96714L, 96703L, 90017L, 96796L, 96714L, 96714L, 96761L, 96712L, 96712L), date = structure(c(8809, 8809, 8847, 8848, 8989, 9041, 9161, 9188, 9201, 9293, 9403, 9437, 9437, 9437, 9437, 9443, 9444, 9457, 9457, 9483), class = "Date")), row.names = c(NA, -20L), class = c("data.table", "data.frame"))
自行尝试的代码(结果不符合预期)
library(data.table) z[,date:=as.Date(date)][,diff_days:=c(NA,diff.Date(date,lag=1L,differences=1L))][, event_id :=1:.N,.(diff_days<=7)]
期望输出
y<- structure(list(zipcode = c(96717, 96730, 96825, 96826, 96720, 96756, 96740, 96819, 96734, 96740, 96714, 96714, 96703, 90017, 96796, 96714, 96714, 96761, 96712, 96712), date = structure(c(761097600, 761097600, 764380800, 764467200, 776649600, 781142400, 791510400, 793843200, 794966400, 802915200, 812419200, 815356800, 815356800, 815356800, 815356800, 815875200, 815961600, 817084800, 817084800, 819331200), class = c("POSIXct", "POSIXt"), tzone = "UTC"), difference_date = c("NA", "0", "38", "1", "141", "52", "120", "27", "13", "92", "110", "34", "0", "0", "0", "6", "1", "13", "0", "26"), id = c(1, 1, 2, 2, 3, 4, 5, 6, 8, 9, 10, 11, 11, 11, 11, 11, 11, 12, 12, 13 )), class = c("data.table", "data.frame"))
正确实现方法
原代码的问题在于分组逻辑错误:.(diff_days<=7)会把所有日期差≤7的行归为同一组,但实际需要的是连续的日期差≤7的行归为同一组,遇到日期差>7时开启新组。
可以通过生成分组标记并累加的方式实现需求:
library(data.table) # 计算当前行与上一行的日期差 z[, diff_days := c(NA, diff(date))] # 生成分组标记:第一行(NA)或日期差>7时标记为1,否则为0 z[, group_flag := as.integer(is.na(diff_days) | diff_days > 7)] # 累加标记得到连续的分组ID z[, id := cumsum(group_flag)] # 可选:生成与期望输出一致的字符型difference_date列 z[, difference_date := as.character(diff_days)] z[is.na(difference_date), difference_date := "NA"] # 查看最终结果 z[]
该逻辑会在每一行需要开启新组时(第一行或日期差超7天)生成1,累加后得到连续的分组ID,完全匹配期望输出的ID规则。
内容的提问来源于stack exchange,提问作者laplaceable
相关产品推荐
相关产品推荐

