在R中基于data.table分析重复序列内事件的时间差
用data.table处理状态序列中的时间差计算
先把你的数据还原成可直接运行的data.table对象,方便后续操作:
library(data.table) dt <- data.table( DateTime = as.POSIXct(c(1533081601.42, 1533081601.98, 1533081601.98, 1533081601.98, 1533081602.02, 1533081928.06, 1533081928.22, 1533081928.22, 1533081928.22, 1533081928.22, 1533081952.34, 1533081952.94, 1533081952.94, 1533081952.94, 1533081952.98, 1533081953.98, 1533081954.14, 1533081954.14, 1533081954.14, 1533081954.14), tz = "UTC"), ID = c(1,3,4,5,2,1,2,3,4,5,1,3,4,5,2,1,2,3,4,5), state = c(0L,0L,0L,0L,0L,1L,1L,1L,1L,1L,0L,0L,0L,0L,0L,1L,1L,1L,1L,1L) )
接下来咱们一步步搞定需求:核心是先给连续相同的state序列分组,再在每个组里以ID=1的时间为基准计算差值。
实现思路:
- 用
rleid(state)生成分组标识:这个函数会给连续相同的state分配同一个组号,完美匹配你说的“同state序列”要求。 - 在每个分组内,提取ID=1对应的
DateTime作为基准时间(你提到ID=1始终是序列首个元素,所以每个组里只会有一条ID=1的记录)。 - 计算每条记录的
DateTime与组内基准时间的差值,得到最终需要的时间差。
完整代码:
dt[, `:=`( group_id = rleid(state), base_time = DateTime[ID == 1] ), by = .(rleid(state))][, time_diff := DateTime - base_time][]
结果说明:
group_id列是每个连续state序列的分组编号,比如前5行state=0对应group 1,接下来5行state=1对应group 2,以此类推。base_time列是每个组内ID=1的时间,同一组内所有行的这个值保持一致。time_diff列就是你要的时间差,默认是以秒为单位的difftime对象;如果需要转成毫秒,用as.numeric(time_diff)*1000即可。
内容的提问来源于stack exchange,提问作者kukuk1de
相关产品推荐
相关产品推荐

