R data.table中具有多个匹配项的滚动联接

R data.table中具有多个匹配项的滚动联接,r,data.table,rolling-computation,R,Data.table,Rolling Computation,我有一个关于滚动联接的评论/问题 设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 <- rbind

我有一个关于滚动联接的评论/问题
设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)

执行
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”,并且
X
的最后一行与
5,6行匹配,可能是
Y
的第7行

对于
X
的第一行,只有
Y
的第一行匹配
X
Y
,因此
Y
的第一行将匹配iff
Y$t[1]
介于
X$t[1]
X$t[1]+0.005之间,但实际上
Y$t[1]
,如下所示:

> X$t[1] - Y$t[1]
Time difference of 0.0009999275 secs
为了在第1行中获得非NA值,需要一个幅值至少等于上述差值的正
roll=
值。e、 g

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

还要注意,
Y
的第5、6和7行的时间不相同。它们的时间越来越长,因此不可能全部匹配:

> dput(Y[["t"]])
structure(c(1371729600.407, 1371729600.285, 1371729600.791, 1371729600.887, 
1371729600.941, 1371729600.942, 1371729600.945), class = c("POSIXct", 
"POSIXt"))
即使
Y
的第5行、第6行和第7行具有相同的时间,如果这些时间与
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
从文档中看,它是如何工作的并不是很清楚,我不得不通过反复试验来发现它是如何工作的
?data.table
确实指出“通常,x的键中不应该有重复项”(在我们的示例中,x是
Y
),因此开发人员可能希望在这种情况下不定义它,并允许将来进行更改


正如您所描述的,使用
mult=
似乎是一个非常有趣的想法,但它似乎不是当前的工作方式。也许将来会这样。

我对此很感兴趣,因为如果我们能得到这些额外的行,我们应该能够处理窗口连接并计算滚动中值、平均值或其他对我来说听起来像是一个功能请求的值(不过我会使用一个非常简单的例子,比如
d=data.table(a=c(1.0,2.0,2.0),by=c(1:3),key='a');d[J(2.1),…]
,因为这一个很难理解)已经把我的评论移到了答案上。我认为OP认为既然在
d=data.table中(a=c(1,2,2),b=c(1:3),key='a')
d[J(2)]
匹配了两个2,所以当
mult
设置为
all时,roll=1
匹配两个2'
我添加了一些额外的探索性代码,以查看在各种情况下会发生什么。请参阅上次添加的代码。
> # 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
> # 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