如何计算一个值的连续重复(允许跳过一次)
How to count sequential repeats of a value (allowing for one skip)
我正在尝试生成一个变量,用于计算“1”在不同变量的前几行中顺序出现的次数。但是,即使有一行缺少 1,我也需要持续计数。(即 10111011 应注册为 8)。我用来计算连续 1 的代码是:
以下代码提供了我正在尝试做的事情的示例:
input <- c(1,0,1,1,0,1,1,0,1,0,1)
dfseq <- data.frame(input)
dfseq$seq <- sequence(rle(as.character(dfseq$input))$lengths)
产生以下数据帧:
data_struc <-
structure(list(
input = c(1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1),
seq = c(1L,
1L, 1L, 2L, 1L, 1L, 2L, 1L, 1L, 1L, 1L)
),
row.names = c(NA,-11L),
class = "data.frame")
但是,我希望序列允许序列中有一行“失败”,这样即使一行包含 0 然后 1 继续,它也会继续计算连续的。它应该只在连续出现两个 0 时停止计数
您使用 rle
的方法是正确的。使用扩展数据集来说明“允许”部分
rle_obj <- rle(dfseq$input)
sum(dfseq$input) + sum(ifelse(rle_obj$lengths[rle_obj$values==0]==1,1,0))
[1] 12
数据
dfseq <- structure(list(input = c(1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0,
0, 1), seq = c(1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1)), row.names = c(NA,
-14L), class = "data.frame")
dfseq
input seq
1 1 1
2 0 1
3 1 1
4 1 2
5 0 1
6 1 1
7 1 2
8 0 1
9 1 1
10 0 1
11 1 1
12 0 1
13 0 2
14 1 1
我会使用带有 OR 条件的滞后变量:
library(dplyr)
dfseq %>% mutate(
cum_result = cumsum(input == 1 | (lag(input) == 1 & lead(input, default = 1) == 1))
)
# input seq cum_result
# 1 1 1 1
# 2 0 1 2
# 3 1 1 3
# 4 1 2 4
# 5 0 1 5
# 6 1 1 6
# 7 1 2 7
# 8 0 1 8
# 9 1 1 9
# 10 0 1 10
# 11 1 1 11
不确定我们是否都理解了这个问题,样本数据没有说明太多,也模糊了任何可能的错误,因为它都遵循 OP 的顺序。为了确保 OP 可以提供期望的结果,并且基于包含根据他的标准会破坏序列的记录的样本集。
我稍微更改了示例数据,这就是我解释问题的方式。
dt <- data.frame(
input = c(1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1)
)
library(data.table)
setDT(dt)
dt[, seq_count := 1:.N, by = rleid(input == 1 | (lag(input) == 1 & lead(input) != 0))]
dt[input == 0 & (lead(input) == 0 | lag(input) == 0), seq_count := NA]
dt
# input seq_count
# 1: 1 1
# 2: 0 2
# 3: 1 3
# 4: 1 4
# 5: 0 NA
# 6: 0 NA
# 7: 1 1
# 8: 0 2
# 9: 1 3
# 10: 1 4
# 11: 0 5
# 12: 1 6
我正在尝试生成一个变量,用于计算“1”在不同变量的前几行中顺序出现的次数。但是,即使有一行缺少 1,我也需要持续计数。(即 10111011 应注册为 8)。我用来计算连续 1 的代码是:
以下代码提供了我正在尝试做的事情的示例:
input <- c(1,0,1,1,0,1,1,0,1,0,1)
dfseq <- data.frame(input)
dfseq$seq <- sequence(rle(as.character(dfseq$input))$lengths)
产生以下数据帧:
data_struc <-
structure(list(
input = c(1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1),
seq = c(1L,
1L, 1L, 2L, 1L, 1L, 2L, 1L, 1L, 1L, 1L)
),
row.names = c(NA,-11L),
class = "data.frame")
但是,我希望序列允许序列中有一行“失败”,这样即使一行包含 0 然后 1 继续,它也会继续计算连续的。它应该只在连续出现两个 0 时停止计数
您使用 rle
的方法是正确的。使用扩展数据集来说明“允许”部分
rle_obj <- rle(dfseq$input)
sum(dfseq$input) + sum(ifelse(rle_obj$lengths[rle_obj$values==0]==1,1,0))
[1] 12
数据
dfseq <- structure(list(input = c(1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0,
0, 1), seq = c(1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1)), row.names = c(NA,
-14L), class = "data.frame")
dfseq
input seq
1 1 1
2 0 1
3 1 1
4 1 2
5 0 1
6 1 1
7 1 2
8 0 1
9 1 1
10 0 1
11 1 1
12 0 1
13 0 2
14 1 1
我会使用带有 OR 条件的滞后变量:
library(dplyr)
dfseq %>% mutate(
cum_result = cumsum(input == 1 | (lag(input) == 1 & lead(input, default = 1) == 1))
)
# input seq cum_result
# 1 1 1 1
# 2 0 1 2
# 3 1 1 3
# 4 1 2 4
# 5 0 1 5
# 6 1 1 6
# 7 1 2 7
# 8 0 1 8
# 9 1 1 9
# 10 0 1 10
# 11 1 1 11
不确定我们是否都理解了这个问题,样本数据没有说明太多,也模糊了任何可能的错误,因为它都遵循 OP 的顺序。为了确保 OP 可以提供期望的结果,并且基于包含根据他的标准会破坏序列的记录的样本集。
我稍微更改了示例数据,这就是我解释问题的方式。
dt <- data.frame(
input = c(1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1)
)
library(data.table)
setDT(dt)
dt[, seq_count := 1:.N, by = rleid(input == 1 | (lag(input) == 1 & lead(input) != 0))]
dt[input == 0 & (lead(input) == 0 | lag(input) == 0), seq_count := NA]
dt
# input seq_count
# 1: 1 1
# 2: 0 2
# 3: 1 3
# 4: 1 4
# 5: 0 NA
# 6: 0 NA
# 7: 1 1
# 8: 0 2
# 9: 1 3
# 10: 1 4
# 11: 0 5
# 12: 1 6