使用 rollapply 从向量中有条件地提取

Conditional extract from vector using rollapply

我正在尝试从满足特定条件的向量中提取一系列值。为了说明这一点,想象一下我有以下向量:

a <- c(1,2,1,3,12,3,2,15,1,1,1,1,4,5,20)

我想隔离总和小于 10 的连续值,以便输出如下所示:

[1] 1 2 1 3
[1] 3 2
[1] 1 1 1 1 4
[1] 5

我可以通过使用 zoo::rollsum() 和逻辑测试

非常低效地解决这个问题
which(rollsum(a,2) < 10)

但为了做到这一点,我必须 运行 多次,每次都增加滚动 window。同样,我可以循环执行此操作,但这显然不是最好的方法。

有人能想出解决办法吗?任何帮助将不胜感激!

以下使用 %/% 对累计和进行计算:

idx <- as.numeric(factor(cumsum(a) %/% 10))
ret <- split(a, idx)
ret <- ret[sapply(ret, function(x) all(x < 10))]

ret;
#$`1`
#[1] 1 2 1 3
#
#$`3`
#[1] 3 2
#
#$`5`
#[1] 1 1 1 1 4
#
#$`6`
#[1] 5

解释:as.numeric(factor(...)) returns split 的索引;在最后一步中,我删除了条目 >=10

请注意,这是假设 OP 的示例中存在错误,数字 4 似乎重复了。如果OP的示例实际上是正确的,那么我不明白这个问题。

我会使用自己的循环。结果与 Maurits 相同:

a <- c(1,2,1,3,12,3,2,15,1,1,1,1,4,5,20)

my.roll <- function(x, limit) {
  res <- vector("list", length(x))
  ctr <- 1
  for (i in seq_along(x)) {
    res[[ctr]] <- c(res[[ctr]], x[i])
    if (sum(res[[ctr]], x[i+1], na.rm = TRUE) > limit) {ctr = ctr+1} else {ctr}
  }
  res <- res[!sapply(res, is.null) & sapply(res, function(x) sum(x) <= limit)]
  return(res)
}
my.roll(a, 10)