我正在尝试找到解决此请求功能的方法:[#2300] Add backwards and firstback to roll=TRUE中提及的this post。
基本上我想在X
Y
的“窗口加入”
{x,y}
)t
中Y
的最后一列([t-w1,t+w2]
的值),该值落入X
区间,其中t是t
中的最后一列,通常{w1,w2}
为时间列,w1=w2=something
为一些整数(可能为w1=0
或library(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]))
)我构建了以下示例(但随意提供另一个/更好的示例)
(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答案感到满意......
答案 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
解决方案来关闭帖子。