You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按ID分组对最近时间戳执行rolljoin滚动连接?

嗨,我来帮你搞定这个按ID匹配最近时间的问题~

首先,你之前的代码核心问题是滚动连接的主表搞反了:你用了DT1[DT2, roll=Inf],这是把DT2作为主表去匹配DT1的数据,而你实际需要的是以DT1为基础,去匹配DT2中对应ID的最近时间记录。

先给你简化一下数据初始化的代码,用lubridate的ymd_hms可以更直接地把字符串转成时间类型:

library(data.table)
library(lubridate)

# 初始化DT1
DT1 <- data.table(
  id = c(7,7,7,3,3,3),
  start_time = ymd_hms(c("2017-11-01 08:37:35","2017-11-01 09:07:44","2017-11-01 09:46:16","2017-11-01 10:32:29","2017-11-01 10:59:25","2017-11-01 13:24:12")),
  cube = c(628,625,469,711,376,628)
)

# 初始化DT2
DT2 <- data.table(
  id = c(7,7,7,3,3,3),
  res_time = ymd_hms(c("2017-11-01 08:35:30","2017-11-01 09:07:48","2017-11-01 09:46:32","2017-11-01 10:31:29","2017-11-01 10:57:25","2017-11-01 13:22:10")),
  res_cube = c(309,625,469,712,375,630)
)

接下来分两种常见需求给你解决方案:

方案1:匹配不晚于start_time的最近res_time(即找start_time之前的最近记录)

这应该是你原本想实现的效果,正确的滚动连接写法是把DT2作为被连接表,DT1作为主表:

# 设置键:先按id分组,再按时间排序
setkey(DT2, id, res_time)
setkey(DT1, id, start_time)

# 滚动连接:为DT1每行匹配同ID下res_time <= start_time的最近记录
ans1 <- DT2[DT1, roll=Inf]
# 调整列顺序让结果更清晰
ans1 <- ans1[, .(id, start_time, cube, res_time, res_cube)]

运行后你会得到符合预期的结果:

id          start_time cube           res_time res_cube
1:  7 2017-11-01 08:37:35  628 2017-11-01 08:35:30      309
2:  7 2017-11-01 09:07:44  625 2017-11-01 08:35:30      309
3:  7 2017-11-01 09:46:16  469 2017-11-01 09:07:48      625
4:  3 2017-11-01 10:32:29  711 2017-11-01 10:31:29      712
5:  3 2017-11-01 10:59:25  376 2017-11-01 10:57:25      375
6:  3 2017-11-01 13:24:12  628 2017-11-01 13:22:10      630

方案2:匹配与start_time时间差最小的res_time(不管时间先后)

如果你需要的是绝对时间最接近的记录(哪怕res_time比start_time晚),可以用分组计算时间差的方法:

# 先按ID做笛卡尔积,得到同ID下DT1和DT2的所有组合
# 然后计算时间差的绝对值,取每组中时间差最小的记录
ans2 <- DT1[DT2, on="id", allow.cartesian=TRUE][
  , time_diff := abs(difftime(start_time, res_time, units="secs"))
][
  , .SD[which.min(time_diff)], by=.(id, start_time, cube)
][
  , .(id, start_time, cube, res_time, res_cube)
]

这个方案的结果会把DT1中id=7的第二行(start_time=09:07:44)匹配到DT2中时间仅差4秒的09:07:48记录,结果如下:

id          start_time cube           res_time res_cube
1:  7 2017-11-01 08:37:35  628 2017-11-01 08:35:30      309
2:  7 2017-11-01 09:07:44  625 2017-11-01 09:07:48      625
3:  7 2017-11-01 09:46:16  469 2017-11-01 09:46:32      469
4:  3 2017-11-01 10:32:29  711 2017-11-01 10:31:29      712
5:  3 2017-11-01 10:59:25  376 2017-11-01 10:57:25      375
6:  3 2017-11-01 13:24:12  628 2017-11-01 13:22:10      630

你可以根据实际需求选择对应的方案~

内容的提问来源于stack exchange,提问作者Ricky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:50:44