R语言按时间间隔分组:为时序数据添加cycle标识列
解决方案
你可以通过时间差判断周期边界,再为每个周期分配起始时间作为cycle标识,具体实现如下:
步骤说明
- 将
date_time转换为可计算的POSIXct时间类型; - 计算相邻行的时间间隔,当间隔远大于连续数据的1秒间隔时(比如超过10分钟/600秒),标记为新周期起点;
- 基于标记生成分组ID,最后为每个分组填充该组的第一个时间值作为
cycle。
完整代码实现
library(dplyr) library(lubridate) # 原始数据 test <- wrapr::build_frame( "date_time" , "automatic", "validate" | "2020-12-01 00:34:58", "sombra" , "sombra" | "2020-12-01 00:34:59", "organismo", "sombra" | "2020-12-01 00:35:00", "partes" , "sombra" | "2020-12-01 00:35:01", "sombra" , "sombra" | "2020-12-01 00:36:02", "organismo", "sombra" | "2020-12-01 00:36:03", "organismo", "partes" | "2020-12-01 06:35:58", "sombra" , "sombra" | "2020-12-01 06:35:59", "partes" , "sombra" | "2020-12-01 06:36:00", "sombra" , "sombra" | "2020-12-01 06:36:01", "sombra" , "partes" | "2020-12-01 06:37:15", "organismo", "sombra" | "2020-12-01 06:37:16", "partes" , "sombra" ) # 生成cycle列 test_result <- test %>% mutate( # 转换为时间类型 date_time = ymd_hms(date_time), # 计算与前一行的时间差,第一行默认与自身差值为0 time_diff = as.numeric(difftime(date_time, lag(date_time, default = first(date_time)), units = "secs")), # 标记新周期起点(间隔超过600秒判定为新周期) is_new_cycle = time_diff > 600, # 生成分组ID cycle_group = cumsum(is_new_cycle) ) %>% # 按分组取第一个时间作为cycle group_by(cycle_group) %>% mutate(cycle = first(date_time)) %>% ungroup() %>% # 转换回字符格式匹配原始数据,移除辅助列 mutate(across(c(date_time, cycle), as.character)) %>% select(-time_diff, -is_new_cycle, -cycle_group) # 查看结果 print(test_result)
结果验证
运行代码后,test_result的cycle列会完全符合你的期望:每个3分钟周期内的所有行,均以该周期的第一个时间值作为标识。
注意事项
- 阈值调整:代码中用600秒(10分钟)作为周期间隔判定标准,你可根据实际数据调整(比如间隔为30分钟时用1800秒),只要远大于连续数据的1秒间隔即可;
- 时间格式:如果原始
date_time已是POSIXct类型,可跳过格式转换步骤。
内容的提问来源于stack exchange,提问作者Wilson Souza
相关产品推荐
相关产品推荐

