使用二进制变量创建计数器
Create Counter with Binary Variable
我正在尝试创建一个计数器变量,每当二进制变量发生变化时它都从 1 开始。
bin <- c(1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0)
df <- as.data.frame(bin)
df <- df %>%
group_by(bin) %>%
mutate(cntr = row_number())
我想得到以下结果:
bin cntr
1 1
0 1
0 2
1 1
1 2
1 3
...
但我得到的是:
1 1
0 1
0 2
1 2
1 3
1 4
我明白这是为什么……我只是不知道如何获得我想要的结果。任何帮助将不胜感激。
我们需要一个 run-length-id
来将相邻的相同元素分组到一个组中。可以使用 data.table
中的 rleid
来完成,或者创建一个逻辑索引,然后进行累加和 (cumsum(bin != lag(bin, default = first(bin)))
)
library(data.table)
library(dplyr)
df %>%
group_by(grp = rleid(bin)) %>%
mutate(cntr = row_number()) %>%
ungroup %>%
select(-grp)
# A tibble: 16 x 2
# bin cntr
# <dbl> <int>
# 1 1 1
# 2 0 1
# 3 0 2
# 4 1 1
# 5 1 2
# 6 1 3
# 7 1 4
#..
在 data.table
中,这可以更紧凑地完成,因为 :=
发生
library(data.table)
setDT(df)[, cntr := rowid(rleid(bin))]
df
# bin cntr
# 1: 1 1
# 2: 0 1
# 3: 0 2
# 4: 1 1
# 5: 1 2
# 6: 1 3
# 7: 1 4
#..
您可以通过组合 sequence
和 rle
轻松做到这一点。不需要软件包。
data.frame(bin, cntr = sequence(rle(bin)$lengths))
# bin cntr
#1 1 1
#2 0 1
#3 0 2
#4 1 1
#5 1 2
#6 1 3
#7 1 4
#8 1 5
#9 0 1
#10 0 2
#11 0 3
#12 0 4
#13 1 1
#14 0 1
#15 1 1
#16 0 1
我正在尝试创建一个计数器变量,每当二进制变量发生变化时它都从 1 开始。
bin <- c(1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0)
df <- as.data.frame(bin)
df <- df %>%
group_by(bin) %>%
mutate(cntr = row_number())
我想得到以下结果:
bin cntr
1 1
0 1
0 2
1 1
1 2
1 3
...
但我得到的是:
1 1
0 1
0 2
1 2
1 3
1 4
我明白这是为什么……我只是不知道如何获得我想要的结果。任何帮助将不胜感激。
我们需要一个 run-length-id
来将相邻的相同元素分组到一个组中。可以使用 data.table
中的 rleid
来完成,或者创建一个逻辑索引,然后进行累加和 (cumsum(bin != lag(bin, default = first(bin)))
)
library(data.table)
library(dplyr)
df %>%
group_by(grp = rleid(bin)) %>%
mutate(cntr = row_number()) %>%
ungroup %>%
select(-grp)
# A tibble: 16 x 2
# bin cntr
# <dbl> <int>
# 1 1 1
# 2 0 1
# 3 0 2
# 4 1 1
# 5 1 2
# 6 1 3
# 7 1 4
#..
在 data.table
中,这可以更紧凑地完成,因为 :=
发生
library(data.table)
setDT(df)[, cntr := rowid(rleid(bin))]
df
# bin cntr
# 1: 1 1
# 2: 0 1
# 3: 0 2
# 4: 1 1
# 5: 1 2
# 6: 1 3
# 7: 1 4
#..
您可以通过组合 sequence
和 rle
轻松做到这一点。不需要软件包。
data.frame(bin, cntr = sequence(rle(bin)$lengths))
# bin cntr
#1 1 1
#2 0 1
#3 0 2
#4 1 1
#5 1 2
#6 1 3
#7 1 4
#8 1 5
#9 0 1
#10 0 2
#11 0 3
#12 0 4
#13 1 1
#14 0 1
#15 1 1
#16 0 1