Мы можем создать функцию с кодировкой длин серий (rle
)
with(rle(x), sum(values == 1 & lengths == 2))
т.е.
fn_len <- function(vec, val, n) {
with(rle(vec), sum(values == val & lengths == n))
}
fn_len(x, 1, 2)
#[1] 63
fn_len(x, 1, 3)
#[1] 34
Если нам нужно получить длины нескольких элементов
sapply(2:5, fn_len, vec = x, val = 1)
#[1] 63 34 19 7
Или другой вариант: rleid
из data.table
library(data.table)
data.table(x)[, .N, .(x, rleid(x))][x==1, sum(N==2)]
#[1] 63
Тесты
set.seed(1)
n <- 1e7
x <- sample(c(0, 1), n, replace = TRUE)
system.time(out1 <- table(scan(text=gsub("0+",";",paste0(x,collapse="")),
sep=";",quiet = T))[2])
# user system elapsed
# 11.818 0.152 11.976
system.time(out2 <- table(strsplit(gsub("0+",";",paste0(x,collapse="")),
";")[[1]])[3])
# user system elapsed
#10.708 0.200 10.913
system.time(fn_len(x, 1, 2))
# user system elapsed
# 0.671 0.399 1.073
Если мы хотим иметь несколько n одновременно,data.table
метод будет быстрее
system.time(data.table(x)[, .N, .(x, rleid(x))][x==1, .N, N])
# user system elapsed
# 2.246 0.285 2.561
system.time(sapply(2:21, fn_len, vec = x, val = 1))
# user system elapsed
# 14.171 6.103 20.323
system.time(table(strsplit(gsub("0+",";",paste0(x,collapse="")),";")[[1]]))
# user system elapsed
# 10.570 0.192 10.770