如何用dplyr或data.table按时间关联表获取事件前后紧邻记录?
按滑板车ID匹配紧邻前后行程记录的实现方案
先把你的示例数据补全规整一下,方便后续演示:
# 示例数据 testScooter <- data.frame( start = as.POSIXct(c( "2018-01-18 22:19:13", "2018-01-18 23:29:22", "2018-01-18 00:22:02", "2018-01-18 00:37:52" )), end = as.POSIXct(c( "2018-01-18 22:26:31", "2018-01-18 23:37:53", "2018-01-18 00:29:21", "2018-01-18 01:06:15" )), id = c(1, 1, 2, 2) )
用dplyr实现
dplyr的lag()和lead()函数刚好能满足取紧邻前后记录的需求,步骤很直观:
- 先按滑板车
id分组,确保我们是在同一个滑板车的行程池里找前后记录 - 对每个分组内的行程按
start时间排序,保证时间顺序绝对正确 - 用
lag()提取前一行的start和end作为前序行程,用lead()提取后一行的作为后序行程
代码实现:
library(dplyr) result_dplyr <- testScooter %>% group_by(id) %>% arrange(start) %>% mutate( prev_start = lag(start), prev_end = lag(end), next_start = lead(start), next_end = lead(end) ) %>% ungroup() # 查看结果 print(result_dplyr)
运行后,每个行程都会带上它的前序(如果有的话)和后序行程时间,没有前后记录的位置会显示NA——这很合理,比如每个滑板车的第一个行程本来就没有前序,最后一个也没有后序。
用data.table实现
如果你的数据量很大,data.table的处理速度会更有优势,它的shift()函数可以灵活实现lag和lead的效果:
library(data.table) # 转成data.table格式 setDT(testScooter) result_dt <- testScooter[order(start), .(start, end, prev_start = shift(start, type = "lag"), prev_end = shift(end, type = "lag"), next_start = shift(start, type = "lead"), next_end = shift(end, type = "lead")), by = id] # 查看结果 print(result_dt)
这里的逻辑和dplyr完全一致:按id分组,每组内按start排序,用shift()分别获取前后行的时间字段,type = "lag"对应前序,type = "lead"对应后序。
内容的提问来源于stack exchange,提问作者iskandarblue
相关产品推荐
相关产品推荐

