5

我有一个关于滚动连接的评论/问题
让 X,Y 为:

set.seed(123);
X <- data.table(x=c(1,1,1,2,2),y=c(T,T,F,F,F),t=as.POSIXct("08:00:00.000",format="%H:%M:%OS")+sample(0:999,5,TRUE)/1e3)
Y <- copy(X)
set.seed(123)
Y[,`:=`(IDX=.I,t=t+sample(c(-5:5)/1e3,5,T))]
Y <- rbindlist(list(Y, X[5,][,IDX:=6][,t:=t+0.001], X[5,][,IDX:=7][,t:=t+0.002]))
setkey(X,x,y,t)
setkey(Y,x,y,t)

在这里X并按Yx,y,t

R) X
   x     y                       t
1: 1 FALSE 2013-06-20 08:00:00.407
2: 1  TRUE 2013-06-20 08:00:00.286
3: 1  TRUE 2013-06-20 08:00:00.788
4: 2 FALSE 2013-06-20 08:00:00.882
5: 2 FALSE 2013-06-20 08:00:00.940
R) Y
   x     y                       t IDX
1: 1 FALSE 2013-06-20 08:00:00.407   3
2: 1  TRUE 2013-06-20 08:00:00.284   1
3: 1  TRUE 2013-06-20 08:00:00.791   2
4: 2 FALSE 2013-06-20 08:00:00.886   4
5: 2 FALSE 2013-06-20 08:00:00.940   6
6: 2 FALSE 2013-06-20 08:00:00.942   7
7: 2 FALSE 2013-06-20 08:00:00.945   5

执行Y[X, roll=-0.005]让你

R) Y[X, roll=-0.005]
       x     y                       t IDX
    1: 1 FALSE 2013-06-20 08:00:00.407  NA => due to precision the roll is no match
    2: 1  TRUE 2013-06-20 08:00:00.286  NA => ok 
    3: 1  TRUE 2013-06-20 08:00:00.788   2 => ok (x,y) matched and 788-791=-3
    4: 2 FALSE 2013-06-20 08:00:00.882   4 => same
    5: 2 FALSE 2013-06-20 08:00:00.940   6 => NOT AN EXACT MATCH (precision)

所以我本来希望在最后一行得到更多的行,因为“mult”的默认行为是“all”,最后一行X5,6, may be 7Y

4

1 回答 1

4

第一排

对于第一行X只有第一行Y有匹配xy所以第一行将Y匹配当且仅当当且但Y$t[1]实际上如下所示:X$t[1]X$t[1] + 0.005Y$t[1] < X$t[1]

> X$t[1] - Y$t[1]
Time difference of 0.0009999275 secs

为了在第 1 行中获得非 NA,需要一个roll=幅度至少等于上述差值的正值。例如

> Y[X, roll=0.001]
   x     y                   t IDX
1: 1 FALSE 2013-06-20 08:00:00   3
2: 1  TRUE 2013-06-20 08:00:00  NA
3: 1  TRUE 2013-06-20 08:00:00  NA
4: 2 FALSE 2013-06-20 08:00:00  NA
5: 2 FALSE 2013-06-20 08:00:00  NA

请注意,您可以通过使用rollends=这样的强制它:

> Y[X, roll = -0.005, rollends = TRUE]
   x     y                   t IDX
1: 1 FALSE 2013-06-20 08:00:00   3
2: 1  TRUE 2013-06-20 08:00:00  NA
3: 1  TRUE 2013-06-20 08:00:00   2
4: 2 FALSE 2013-06-20 08:00:00   4
5: 2 FALSE 2013-06-20 08:00:00   6

最后一排

对于X只有第 5 行Y匹配的最后一行,而不是第 5、6 和 7 行,因为只有最近的符合条件的行是匹配的。 mult=仅适用于多个匹配项,通常不适用于roll=(有关例外情况,请参见底部的示例):

另请注意,第 5、6 和 7 行Y的时间不同。它们的次数越来越多,因此它们不可能都匹配:

> dput(Y[["t"]])
structure(c(1371729600.407, 1371729600.285, 1371729600.791, 1371729600.887, 
1371729600.941, 1371729600.942, 1371729600.945), class = c("POSIXct", 
"POSIXt"))

即使第 5、6 和 7 行的Y时间相同,如果这些时间与最后一行中的时间不同,X那么也只会得到一行。

> # times in rows 5, 6 and 7 of Y2 are same
> Y2 <- copy(Y)
> Y2[, t:= t[c(1:4, 5, 5, 5)]]
> setkey(Y2, x, y, t)
> Y2[X, roll = -0.005]
   x     y                   t IDX
1: 1 FALSE 2013-06-20 08:00:00  NA
2: 1  TRUE 2013-06-20 08:00:00  NA
3: 1  TRUE 2013-06-20 08:00:00   2
4: 2 FALSE 2013-06-20 08:00:00   4
5: 2 FALSE 2013-06-20 08:00:00   6

仅当“Y”的第 5、6 和 7 行具有相同的时间并且最后一行X也具有该时间的情况下,一个人会多次超时,并且在这种情况下mult=可以应用:

> # time in row 5 of X2 same as the times in rows 5, 6 and 7 of Y2
> X2 <- copy(X)
> X2[, t:=c(t[1:4], Y2[["t"]][5])]
> Y2[X2, roll = -0.005]
   x     y                   t IDX
1: 1 FALSE 2013-06-20 08:00:00  NA
2: 1  TRUE 2013-06-20 08:00:00  NA
3: 1  TRUE 2013-06-20 08:00:00   2
4: 2 FALSE 2013-06-20 08:00:00   4
5: 2 FALSE 2013-06-20 08:00:00   6
6: 2 FALSE 2013-06-20 08:00:00   7
7: 2 FALSE 2013-06-20 08:00:00   5
> 
> Y2[X, roll = -0.005, mult = "first"]
   x     y                   t IDX
1: 1 FALSE 2013-06-20 08:00:00  NA
2: 1  TRUE 2013-06-20 08:00:00  NA
3: 1  TRUE 2013-06-20 08:00:00   2
4: 2 FALSE 2013-06-20 08:00:00   4
5: 2 FALSE 2013-06-20 08:00:00   6

从文档中看它是如何工作的并不是很清楚,我不得不通过反复试验来发现它是如何工作的。 ?data.table确实说“通常,x 的键中不应该有重复项”(在我们的示例中,这里的 x 是Y),因此开发人员可能希望在这种情况下不定义它,并对未来的更改持开放态度。

按照您的描述使用的想法mult=似乎是一个非常有趣的想法,但它似乎不是它目前的工作方式。也许将来可以。

于 2013-06-20T17:05:39.643 回答