2017-01-26 63 views
2

我有一個類似於以下內容的數據表。請注意,當vals0時,該標誌爲1,並在其他地方丟失。使用R數據中的序列填充NA值

dt <- data.table(vals = c(0,2,4,1,0,4,3,0,3,4)) 
dt[vals == 0, flag := 1] 

> dt 
    vals flag 
1: 0 1 
2: 2 NA 
3: 4 NA 
4: 1 NA 
5: 0 1 
6: 4 NA 
7: 3 NA 
8: 0 1 
9: 3 NA 
10: 4 NA 

我想輸出看起來像下面的seq列。也就是說,該列需要包含從1開始的一組序列,每當vals0並且當vals0時計數直到下一行。 flag只有在幫助實現所述目標時纔有用。

> dt 
    vals seq 
1: 0 1 
2: 2 2 
3: 4 3 
4: 1 4 
5: 0 1 
6: 4 2 
7: 3 3 
8: 0 1 
9: 3 3 
10: 4 3 

本來,我想使用cumsum()莫名其妙,但我無法弄清楚如何有效地使用它。

我目前的解決方案非常難看。

dt <- data.table(vals = c(0,2,4,1,0,4,3,0,3,4)) 
dt[vals == 0, flag := 1] 
dt[, flag_rleid := rleid(flag)] 

# group on the flag_rleid column 
dt[, flag_seq := seq_len(.N), by = flag_rleid] 
# hideous subsetting to avoid incrementing the first appearance of a 1 
dt[vals != 0, flag_seq := flag_seq + 1] 

# flag_seq is the desired column 
> dt 
    vals flag flag_rleid flag_seq 
1: 0 1   1  1 
2: 2 NA   2  2 
3: 4 NA   2  3 
4: 1 NA   2  4 
5: 0 1   3  1 
6: 4 NA   4  2 
7: 3 NA   4  3 
8: 0 1   5  1 
9: 3 NA   6  2 
10: 4 NA   6  3 

任何改進的讚賞。

回答

2

我們可以用一個邏輯索引與cumsum創建分組變量,然後根據我們得到的序列科拉姆

dt[, flag_seq := seq_len(.N), cumsum(vals ==0)] 
dt 
# vals flag flag_seq 
# 1: 0 1  1 
# 2: 2 NA  2 
# 3: 4 NA  3 
# 4: 1 NA  4 
# 5: 0 1  1 
# 6: 4 NA  2 
# 7: 3 NA  3 
# 8: 0 1  1 
# 9: 3 NA  2 
#10: 4 NA  3