我正在尝试计算二进制矢量的获胜条纹序列。给定向量
set.seed(2)
x <- sample(c(0,1), 10, replace = TRUE)
[1] 0 1 1 0 1 1 0 1 0 1
我想计算每次为零时的“重置”值的总和。 因此,在这种情况下,该函数的输出应为
[1] 0 1 2 0 1 2 0 1 0 1
在R上最简单的方法是什么?
答案 0 :(得分:13)
我们可以使用ave
并在向量中每次出现0的情况下使用cumsum
创建一个分组变量,并对每个组中不包含0的连续数字进行计数。
ave(x, cumsum(x==0), FUN = seq_along) - 1
#[1] 0 1 2 0 1 2 0 1 0 1
答案 1 :(得分:2)
我们可以将rleid
与rowid
一起使用
library(data.table)
rowid(rleid(x)) * x
#[1] 0 1 2 0 1 2 0 1 0 1
x <- c(0, 1, 1, 0, 1, 1, 0, 1, 0, 1)
答案 2 :(得分:0)
我建议使用runner软件包和函数streak_run
来计算连续出现的次数。也可以在滑动窗口上进行计算(例如,最后5个观测值),更多信息请参见github documentation
library(runner)
streak <- streak_run(x)
streak[x == 0] <- 0
print(streak)
# [1] 0 1 2 0 1 2 0 1 0 1
将速度与其他解决方案进行比较
fun_ave <- function (x) ave(x, cumsum(x==0), FUN = seq_along) - 1
fun_dt <- function (x) rowid(rleid(x)) * x
run <- function(x) {
out <- streak_run(x)
out[x == 0] <- 0
out
}
microbenchmark::microbenchmark(
run,
fun_ave(x),
fun_dt(x),
times = 1000L
)
# Unit: nanoseconds
# expr min lq mean median uq max neval
# run 48 58.5 197.676 207.5 250.0 12599 1000
# fun_ave(x) 122984 137144.0 173577.501 146211.5 193241.5 3243640 1000
# fun_dt(x) 24954 28959.0 42959.954 36262.5 40843.0 4141624 1000