使用lubridate按10天间隔对各ID数据分组并生成列表的问题
R实现按ID分组后各自按10天日期间隔拆分数据集
原代码问题
你写的代码直接硬生成了interval列:每10行重复同一个数值,完全没有和数据中的ID、日期字段关联,所以无法实现「每个ID单独按10天日期间隔分组」的需求,自然会出现同一时间区间的记录分到不同组的问题。
正确实现方案
实现逻辑
- 先对全表按ID、日期排序,保证每个ID的日期按时间顺序排列
- 按ID分组后,计算每条记录的日期与该ID最早日期的天数差,除以10向下取整得到间隔编号,这样每个ID内部属于同一个10天区间的记录会对应同一个间隔编号
- 按需要的层级拆分分组即可得到目标列表
可运行代码
library(tidyverse) library(lubridate) # 生成测试数据 date <- rep_len(seq(dmy("26-12-2010"), dmy("20-12-2013"), by = "days"), 500) ID <- rep(seq(1, 5), 100) df <- data.frame(date = date, x = runif(length(date), min = 60000, max = 80000), y = runif(length(date), min = 800000, max = 900000), ID) # 每个ID独立计算10天间隔的实现 result <- df %>% arrange(ID, date) %>% group_by(ID) %>% mutate( day_diff = as.numeric(date - min(date)), interval = floor(day_diff / 10) + 1 # 间隔编号从1开始计数 ) %>% ungroup() %>% # 先按10天间隔拆分,再在每个间隔内按ID拆分 group_split(interval) %>% map(~ group_split(.x, ID)) # 查看前2个间隔的分组结果 head(result, 2)
全局统一10天间隔的可选实现
如果你需要所有ID共享同一套10天时间区间划分,只需要把间隔计算步骤放到ID分组外,用全表的最小日期计算差值即可:
result_global <- df %>% arrange(date, ID) %>% mutate( day_diff = as.numeric(date - min(date)), interval = floor(day_diff / 10) + 1 ) %>% group_split(interval) %>% map(~ group_split(.x, ID))
内容的提问来源于stack exchange,提问作者John Huang
相关产品推荐
相关产品推荐

