r - R data.table 外连接与 roll="nearest" 有约束
问题描述
更新:我认为这主要是我想要的,但现在我有多个匹配项。这是我认为的另一个问题。能够为非 equi 连接组合滚动连接会很好。
df2[ copy(df1)[, `:=`(TargDate2 = TargDate + hours(4) , TargDate1 = TargDate -hours(4) )],
`:=`( Value = i.Value, TargDate.df1 = TargDate ),
on = .(ID == ID, TargDate >= TargDate1, TargDate <= TargDate2) ]
有没有办法使用 data.table 包中的滚动连接来匹配基于某个约束(例如,4 小时)内最近的日期时间值的两个数据帧,但保留两个表的所有值(例如:merge(. ..,全部=T))?
library(data.table)
library(lubridate)
set.seed(1)
df1 <- data.frame(ID=sample(1:3,10, replace=T),TargDate=ymd_hms(Sys.time() + sort(sample(1e2:1e5, 10))),
Value=rnorm(10,10,0.5) )
set.seed(21)
df2 <- data.frame(ID=sample(1:3,20, replace=T), TargDate=ymd_hms(Sys.time() + sort(sample(1e2:1e5, 20))),
ValueMatch=rnorm(20,50,15) )
setDT(df1)
setDT(df2)
setkey(df2, ID, TargDate)[, dateMatch:=TargDate]
# This is an inner match to df1 with DateTarg and Value from df1
# and ValueMatch and dateMatch from df2
df2[df1, roll="nearest"]
# 60 seconds * 60 minutes * 4 hours
four_hours <- 60*60*4
df2[df1, roll=-four_hours]
包含 df1 和 df2 中所有行的数据框,匹配的行已合并。
解决方案
这是加入 <= 4 小时 df2 的行的 data.table 方法。在df2 的副本上使用非 equi联接,其中已创建一个新的列Targdate2
(=TargetDate + 4 小时)以进行非 equi 联接。
df1[ copy(df2)[, TargDate2 := TargDate + hours(4)],
`:=`( ValueMatch = i.ValueMatch, TargDate.df2 = TargDate ),
on = .(ID == ID, TargDate >= TargDate, TargDate <= TargDate2) ]
# ID TargDate Value ValueMatch TargDate.df2
# 1: 1 2019-06-05 13:32:48 10.755891 NA <NA>
# 2: 2 2019-06-05 14:21:47 10.194922 NA <NA>
# 3: 2 2019-06-05 19:11:32 9.689380 NA <NA>
# 4: 3 2019-06-05 19:18:21 8.892650 46.59552 2019-06-05 17:56:47
# 5: 1 2019-06-05 22:27:28 10.562465 NA <NA>
# 6: 3 2019-06-06 03:42:42 9.977533 22.48528 2019-06-06 03:12:42
# 7: 3 2019-06-06 04:33:36 9.991905 43.88468 2019-06-06 04:26:16
# 8: 2 2019-06-06 06:00:34 10.471918 NA <NA>
# 9: 2 2019-06-06 06:13:10 10.410611 63.67443 2019-06-06 06:10:11
#10: 1 2019-06-06 12:10:15 10.296951 51.20187 2019-06-06 08:45:39