窗口(又名滚动)与data.table连接

时间:2013-01-25 14:49:41

标签: r join data.table

我正在尝试找到解决此请求功能的方法:[#2300] Add backwards and firstback to roll=TRUE中提及的this post

基本上我想在X

中查看以下Y的“窗口加入”
  1. 在前n列(在以下示例{x,y}
  2. 中左连接
  3. AND选择tY的最后一列([t-w1,t+w2]的值),该值落入X区间,其中t是t中的最后一列,通常{w1,w2}为时间列,w1=w2=something为一些整数(可能为w1=0library(data.table) 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]))
  4. 我构建了以下示例(但随意提供另一个/更好的示例)

    (w1,w2) = (.002,.002)

    使用R) X R) Y x y t x y t IDX 1: 1 TRUE 2013-01-25 08:00:00.286 1: 1 TRUE 2013-01-25 08:00:00.284 1 2: 1 TRUE 2013-01-25 08:00:00.788 2: 1 TRUE 2013-01-25 08:00:00.791 2 3: 1 FALSE 2013-01-25 08:00:00.407 3: 1 FALSE 2013-01-25 08:00:00.407 3 4: 2 FALSE 2013-01-25 08:00:00.882 4: 2 FALSE 2013-01-25 08:00:00.886 4 5: 2 FALSE 2013-01-25 08:00:00.940 5: 2 FALSE 2013-01-25 08:00:00.945 5 6: 2 FALSE 2013-01-25 08:00:00.941 6 #by hand 7: 2 FALSE 2013-01-25 08:00:00.942 7 #by hand

    R) ans
       x     y                       t IDX
    1: 1  TRUE 2013-01-25 08:00:00.286   1
    2: 1  TRUE 2013-01-25 08:00:00.788  NA
    3: 1 FALSE 2013-01-25 08:00:00.407   3
    4: 2 FALSE 2013-01-25 08:00:00.882  NA
    5: 2 FALSE 2013-01-25 08:00:00.940  6,7
    

    结果将是

    IDX

    但是:Y如果有几行X(可以有比NA更多的行)匹配,只有一行,或{{1}如果没有匹配的话。

    我也会对一些非data.table答案感到满意......

2 个答案:

答案 0 :(得分:1)

这是一个尝试,不是很优雅,没有data.table但是plyr。不知道它是否对你有用。

示例数据:

X <- data.frame(x=c(1,1,1,2,2),y=c(T,T,F,F,F),t=rep(1,5)+sample(0:999,5,TRUE)/1e3)
Y <- data.frame(x=c(1,1,1,2,2),y=c(T,T,F,F,F),t=rep(1,5)+sample(0:999,5,TRUE)/1e3, IDX=1:5)
w1 <- 0.3
w2 <- 0.3

给出了:

R> X
  x     y     t
1 1  TRUE 1.880
2 1  TRUE 1.364
3 1 FALSE 1.288
4 2 FALSE 1.170
5 2 FALSE 1.172
R> Y
  x     y     t IDX
1 1  TRUE 1.482   1
2 1  TRUE 1.252   2
3 1 FALSE 1.216   3
4 2 FALSE 1.674   4
5 2 FALSE 1.047   5

然后您可以使用以下代码:

m <- merge(X,Y, by=c("x","y"), all.x=TRUE, all.y=FALSE)
m <- m[m$t.x>m$t.y-w1 & m$t.x<m$t.y+w2,]
m <- ddply(m, c("x","y","t.x"), summarize, IDX=list(IDX))
names(m) <- c("x","y","t","IDX")
merge(X, m, by=c("x","y","t"), all.x=TRUE, all.y=FALSE)

这给出了以下结果:

  x     y     t  IDX
1 1 FALSE 1.288    3
2 1  TRUE 1.364 1, 2
3 1  TRUE 1.880   NA
4 2 FALSE 1.170    5
5 2 FALSE 1.172    5

答案 1 :(得分:1)

以下是data.table(v.1.8.7 r797)中juba代码的翻译

setkey(X,x,y,t); setkey(Y,x,y,t)
m <- merge(X,Y, by=c("x","y"), all.x=TRUE, all.y=FALSE, allow.cartesian=TRUE)
m <- m[t.x>=(t.y-w1) & t.x<=(t.y+w2)]
m <- m[, list(IDX=list(IDX)), by=c("x","y","t.x")];
setnames(m,"t.x","t");
m <- m[X];

我明白了(注意NULL,Matthew Dowle可能会解释为什么我们这样做而不是NA

R) m
   x     y                       t IDX
1: 1 FALSE 2013-01-25 08:00:00.407   3
2: 1  TRUE 2013-01-25 08:00:00.286   1
3: 1  TRUE 2013-01-25 08:00:00.788
4: 2 FALSE 2013-01-25 08:00:00.882
5: 2 FALSE 2013-01-25 08:00:00.940 6,7

我会等专家说出是否是data.table-optimal解决方案来关闭帖子。