окно (также известное как вращение) объединяется с data.table

Я пытаюсь найти способ обойти эту функцию запроса: [# 2300] Добавьте backwards и firstback к roll = TRUE, который был упомянут в этот пост.

В основном я хотел бы выполнить следующее "оконное соединение" X поиска в Y

  1. левое соединение первых n столбцов (в следующем примере {x,y})
  2. И выберите значения последнего столбца (t в следующем примере) в Y, который попадает в [t-w1,t+w2] интервал, где t - последний столбец в X, обычно 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, если ни одна не соответствует.

Я был бы счастлив и с некоторыми ответами, не относящимися к data.table ...


person statquant    schedule 25.01.2013    source источник


Ответы (2)


Вот попытка, не очень элегантная, без 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
person juba    schedule 25.01.2013
comment
Хороший материал !, я получаю ожидаемый ответ с m <- m[m$t.x>=(m$t.y-w1) & m$t.x<=(m$t.y+w2),]. Спасибо, подожду data.table ответа - person statquant; 25.01.2013

Вот перевод кода джубы в data.table (v.1.8.7 r797)

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, Мэтью Доул может объяснить, почему мы получаем это вместо 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 решение закрыть сообщение.

person statquant    schedule 25.01.2013
comment
Вы получаете NULL, потому что ищете c(1,2,NA,NA,3) в списке (IDX). Сравните integer(3)[c(1,2,NA,NA,3)] и as.list(integer(3))[c(1,2,NA,NA,3)]. - person user1935457; 25.01.2013