2017-01-23 51 views
4

我在R中使用data.table來存儲時間序列。我想要返回一個子集,使得所選時間的連續行與所選最後一行相距至少N秒,例如,如果我有子集時間系列,以便選定行相差一定的最短時間

library(data.table) 
x <- data.table(t=c(0,1,3,4,5,6,7,10,16,17,18,20,21), v=1:13) 
x 
    t v 
1: 0 1 
2: 1 2 
3: 3 3 
4: 4 4 
5: 5 5 
6: 6 6 
7: 7 7 
8: 10 8 
9: 16 9 
10: 17 10 
11: 18 11 
12: 20 12 
13: 21 13 

,我想品嚐是至少5秒分開,從第一行開始行,那麼我應該得到一個data.table隨着時間的推移/值對:

y <- x[...something...] 
y 
    t v 
1: 0 1 
2: 5 5 
3: 10 8 
4: 16 9 
5: 21 13 

時間樣本不一定要有規律的間隔,所以我不能每隔M行。當然,我可以通過手動循環訪問data.table行來做到這一點,但我想知道是否有一種更方便的方法來使用data.tables索引來表達這一點。

回答

4

這裏有幾種方法可以使用滾動加入到找到一組行,w的,在你的子集:

t_plus = 5 

# one join per row visited 
w <- c() 
nxt <- 1L 
while(!is.na(nxt)){ 
    w <- c(w, nxt) 
    nxt <- x[.(t[nxt]+t_plus), on=.(t), roll=-Inf, which=TRUE] 
} 

# join once on all rows 
w0 <- x[.(t+5), on=.(t), roll=-Inf, which=TRUE] 

w <- c() 
nxt <- 1L 
while (!is.na(nxt)){ 
    w <- c(w, nxt) 
    nxt <- w0[nxt] 
} 

然後你就可以像子集x[w]


評論

原則上,有可能是「開至少5秒」滿足OP的條件其他子集;這只是從第一行迭代中找到的一個。

第二種方法是基於@DavidArenburg's answer到Q &亨裏克鏈接上面。雖然這個問題似乎是一樣的,但我無法在這裏充分發揮作用。

一般來說,在R中循環生長東西是一個壞主意(就像我在這裏用w所做的那樣)。如果您遇到性能問題,那麼這可能是在此代碼中改進的一個很好的方面。

+0

似乎'findInterval'也應該在這裏工作,但我無法想象它。 – Frank

+0

哎呀,我認爲答案是「否」,對此沒有方便的索引範例。如果我的R實現成爲瓶頸,我可能會把它外包給Rcpp。謝謝您的幫助。 – Anthony

+0

@Anthony是的,我認爲你說的沒有一個方便的方法是正確的,但我也認爲你低估了規則的複雜性「最大的一組行至少相距5秒」。如果你不關心「最大集合」部分,那麼它就容易得多,並且不需要迭代計算:'x [x [。(t = seq(t [1L],t [.N ],by = 5 * 2)),on =。(t),roll = TRUE,which = TRUE,mult =「first」]]'從每個10秒間隔選擇一個數字,滿意。無論如何,如果你找到一個好的Rcpp方式,也許你可以把它作爲答案發布,這樣我們就可以看到它。 – Frank