我需要为特定条件创建一个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
我试图仅为flag == 1创建一个id变量,但可悲的是还标识了flag == 0,我的命令结果和期望结果的示例是:
a %>%
mutate(try_seq = cumsum(c(TRUE, diff(flag) != 0)))
> id flag try_seq desire_seq
1 1 0 1 NA
2 2 0 1 NA
3 3 0 1 NA
4 4 1 2 1
5 5 1 2 1
6 6 0 3 NA
7 7 0 3 NA
8 8 1 4 2
9 9 0 5 NA
10 10 0 5 NA
10 10 0 5 NA
答案 0 :(得分:1)
这将返回您要查找的结果:
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
检查变量的正变化。
答案 1 :(得分:0)
我们可以使用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
答案 2 :(得分:0)
我们也可以不使用任何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
或使用data.table
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