2017-01-26 5 views
2

Ich habe eine Datentabelle, die ungefähr wie folgt aussieht. Beachten Sie, dass das Flag 1 ist, wenn vals0 ist und woanders fehlt.Füllen von NA-Werten mit einer Sequenz in R data.table

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 

würde ich die Ausgabe wie die seq Spalte unten aussehen mögen. Das heißt, die Spalte muss einen Satz von Sequenzen beginnend mit 1 enthalten, wann immer vals0 ist, und aufwärts bis zur nächsten Zeile, wenn vals0 ist. Die flag ist nur hilfreich, wenn es hilft, das beschriebene Ziel zu erreichen.

> 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 

Ursprünglich dachte ich an cumsum() irgendwie, aber ich kann nicht herausfinden, wie man es effektiv zu nutzen.

Meine aktuelle Lösung ist ziemlich hässlich.

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 

Alle Verbesserungen werden geschätzt.

Antwort

2

Wir können einen logischen Index mit cumsum verwenden, um die Gruppenvariable zu erstellen und dann auf der Grundlage, dass wir die Sequenz colum

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 
bekommen