R 为具有特定条件的标志创建id序列
我需要为一个特定的条件创建一个id序列:flag==1,我的问题的一个例子是: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
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