R 为具有特定条件的标志创建id序列

R 为具有特定条件的标志创建id序列,r,dplyr,R,Dplyr,我需要为一个特定的条件创建一个id序列:flag==1,我的问题的一个例子是: library(dplyr) set.seed(123) a <- data.frame(id = 1:10, flag = rbinom(10,1,0.2)) print(a) id flag 1 1 0 2 2 0 3 3 0 4 4 1 5 5 1 6 6 0 7 7 0 8 8 1 9

我需要为一个特定的条件创建一个id序列:flag==1,我的问题的一个例子是:

library(dplyr)
set.seed(123)
a <- data.frame(id = 1:10,
                flag = rbinom(10,1,0.2))
print(a)

   id flag
1   1    0
2   2    0
3   3    0
4   4    1
5   5    1
6   6    0
7   7    0
8   8    1
9   9    0
10 10    0

这将返回您要查找的结果:

cumsum(c(a$flag[1], diff(a$flag)) > 0) * NA^!a$flag
 [1] NA NA NA  1  1 NA NA  2 NA NA

NA^a$flag
技巧使用的思想是,任何提升到0次方的值都是1。否则,我们使用
diff
检查变量的正变化。

我们可以使用
rle
为每个1创建一个序列,否则将其更改为
NA

library(dplyr)

a %>%
  mutate(ans_seq = ifelse(flag == 1, with(rle(flag == 1), 
                         rep(cumsum(!values), lengths)), NA))


#   id flag ans_seq
#1   1    0      NA
#2   2    0      NA
#3   3    0      NA
#4   4    1       1
#5   5    1       1
#6   6    0      NA
#7   7    0      NA
#8   8    1       2
#9   9    0      NA
#10 10    0      NA

也可以仅使用基本R作为

with(a, ifelse(flag == 1, with(rle(flag == 1), rep(cumsum(!values), lengths)), NA))
#[1] NA NA NA  1  1 NA NA  2 NA NA

我们也可以使用
rle
而不使用任何
ifelse

library(dplyr)
na_if(inverse.rle(within.list(rle(a$flag), {
    i1 <- as.logical(values)
    values[i1] <- seq_along(values[i1])} )), 0)
#[1] NA NA NA  1  1 NA NA  2 NA NA
library(dplyr)
na_if(inverse.rle(within.list(rle(a$flag), {
    i1 <- as.logical(values)
    values[i1] <- seq_along(values[i1])} )), 0)
#[1] NA NA NA  1  1 NA NA  2 NA NA
library(data.table)
setDT(a)[, grp := rleid(flag)][flag != 0, desire_seq := .GRP , grp][, grp := NULL][]
#    id flag desire_seq
# 1:  1    0         NA
# 2:  2    0         NA
# 3:  3    0         NA
# 4:  4    1          1
# 5:  5    1          1
# 6:  6    0         NA
# 7:  7    0         NA
# 8:  8    1          2
# 9:  9    0         NA
#10: 10    0         NA