我有一个类似于以下内容的数据表。请注意,当1
为vals
且其他位置缺失时,该标记为0
。
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
列。也就是说,每当vals
为0
时,列需要包含从1开始的一系列序列,并且当vals
为0
时,该列计数到下一行。 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
赞赏任何改进。
答案 0 :(得分: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