2017-05-17 16 views
-3

沿着單調序列我有一個data.table說DT發現與服用順序重新啓動時達到最大考慮

name <- letters[1:22] 
score <- c(42, 82, 43, 32, 47, 48, 49, 50, 54, 59, 
      76, 9, 13, 88, 91, 99, 4, 6, 8, 12, 14, 15) 
class <- rep(c('c1', 'c2', 'c3'), c(7, 3, 12)) 
dt <- data.table(name, score, class) 

它看起來像:

> dt 
    name score class 
1: a 42 c1 
2: b 82 c1 
3: c 43 c1 
4: d 32 c1 
5: e 47 c1 
6: f 48 c1 
7: g 49 c1 
8: h 50 c2 
9: i 54 c2 
10: j 59 c2 
11: k 76 c3 
12: l  9 c3 
13: m 13 c3 
14: n 88 c3 
15: o 91 c3 
16: p 99 c3 
17: q  4 c3 
18: r  6 c3 
19: s  8 c3 
20: t 12 c3 
21: u 14 c3 
22: v 15 c3 

我只要求那些跟隨記錄每個班級得分的單調順序。在這種情況下,只有分數爲42的記錄,分類爲c1的分數爲43,47,48,49,對於給定的分類,最多可以有3個連續的無序分數。第2行(分數= 82)因此也是無序的分數。

對於c2級,得分爲50,54,59。

在得分爲76,88,91,99,04,06,08,12,14,15的「c3」類記錄中,此處序列已達到最大值(99),然後重新開始。 「c3」類中的09和13分不在單調序列中,因此需要刪除。

我想刪除那些提及的分數對於每個類c1,c2,c3都沒有按順序排列的記錄。共有100萬條記錄。

最終輸出必須看起來像。

> dt 
    name score class 
1: a 42 c1 
2: c 43 c1 
3: e 47 c1 
4: f 48 c1 
5: g 49 c1 
6: h 50 c2 
7: i 54 c2 
8: j 59 c2 
9: k 76 c3 
10: n 88 c3 
11: o 91 c3 
12: p 99 c3 
13: q  4 c3 
14: r  6 c3 
15: s  8 c3 
16: t 12 c3 
17: u 14 c3 
18: v 15 c3 

爲了找到單調序列我曾嘗試:

dt <- dt[, .SD[score == cummax(score)],class] 

但這也刪除其達到最大值後重新啓動序列。

實際上最大的序列重新啓動,如果999999,雖然對於這個例子,我已經取得最大爲99.我該怎麼做。

+1

我不確定您的納入條件是否明確。你可以嘗試並更加明確嗎? – MichaelChirico

+0

該序列必須是單調的,我需要刪除之間的任何失序,同時也必須照顧序列重新啓動 –

+0

dt [,保持:=分數> = cummax(shift(分數,填充=第一(分數))), by =。(class,rleid(score == 99))]這也是照顧單調序列,也就是最大化條件,但它將第3行從第c1行刪除, 82之前提到過,雖然這是無序的,必須刪除 –

回答

0

這可能大多采用dplyr

dts <- dt %>% 
     group_by(class) %>% 
     mutate(f = ifelse((score - lead(score) > 0 & lag(score) - score <0) | 
          (score - lead(score) < 0 & lag(score) - score > 0) , 1, 0)) %>% 
     mutate(f = ifelse(is.na(f), 0, f)) %>% 
     mutate(g = ifelse((lead(f) == 1 & f == 1)| (lag(f) == 1 & f == 1), 2, 0))) %>% 
     filter(f + g != 1) 

正如我所說的,這將主要讓你有來完成。問題是你會得到19個觀察結果(保留id = m)而不是18.你可以做的是重新運行這個dts以消除id = m。或者如果這是更大集合的子集,則可以使用forwhile循環。原因是因爲leadlag函數只檢查一個索引的上下。

另一種選擇是舊式技術,稱爲push-pop技術,但我會遠離這一點。

相關問題