R 矢量中有条件地增加值(有条件地重新启动运行求和)--矢量化版本?

R 矢量中有条件地增加值(有条件地重新启动运行求和)--矢量化版本?,r,vectorization,R,Vectorization,给定一个二进制值向量out_2下面的代码返回一个向量 与out\u 2长度相同的调用out\u 1。 out_1的条目统计在下一个符号切换之前留在out_2中的连续类似项目的数量。如果你打印最后的cbind()我想你会明白我的意思 library(zoo) n = 10 out_2 = rep(NA, n) out_2[sample.int(n, 3)] = sample(c(-1, 1), 3, replace = TRUE) out_2 = zoo::na.locf(ou

给定一个二进制值向量
out_2
下面的代码返回一个向量 与
out\u 2
长度相同的调用
out\u 1
out_1
的条目统计在下一个符号切换之前留在
out_2
中的连续类似项目的数量。如果你打印最后的
cbind()
我想你会明白我的意思

  library(zoo)
  n = 10
  out_2 = rep(NA, n)
  out_2[sample.int(n, 3)] = sample(c(-1, 1), 3, replace = TRUE)
  out_2 = zoo::na.locf(out_2)
  out_1 = out_2
  out_1[length(out_2)] = 1
  for(i in (length(out_2) - 1):1){
    out_1[i] = ifelse(out_2[i + 1] == out_2[i], out_1[i + 1] + 1, 1)  
  }
cbind(out_1, out_2)

我想知道是否有一种一行向量化的方法可以从
out\u 2
中获取
out\u 1
(即,对显式for循环进行向量化)

此解决方案迭代分组的连续值(而不是像您的示例中那样迭代
out\u 2
)。基本上,我们将连续的值分组,检查这个组有多大,并创建向量
N:1

foo <- rle(out_2)
cbind(unlist(sapply(foo$lengths, function(x) x:1)), 
      rep(foo$values, foo$lengths))

foo此解决方案迭代分组的连续值(而不是像您的示例中那样迭代
out_2
)。基本上,我们将连续的值分组,检查这个组有多大,并创建向量
N:1

foo <- rle(out_2)
cbind(unlist(sapply(foo$lengths, function(x) x:1)), 
      rep(foo$values, foo$lengths))

foo我会从base
R
使用
rle
。棘手的部分是得到
out_1
向量的相反顺序,因此它必须(?)通过'lappy'

out_1<- unlist(lapply(rle(out_2)$lengths, function(x) seq(x, by=-1)))
如果您可以灵活地处理输出,并且不需要按相反的顺序处理,那么您可以简单地使用
sequence
函数

out_1<- sequence(rle(out_2)$lengths)
cbind(out_1, out_2)
      out_1 out_2
 [1,]     1    -1
 [2,]     2    -1
 [3,]     1     1
 [4,]     1    -1
 [5,]     2    -1
 [6,]     3    -1
 [7,]     4    -1
 [8,]     5    -1
 [9,]     6    -1

out\u 1我会从基本
R
使用
rle
。棘手的部分是得到
out_1
向量的相反顺序,因此它必须(?)通过'lappy'

out_1<- unlist(lapply(rle(out_2)$lengths, function(x) seq(x, by=-1)))
如果您可以灵活地处理输出,并且不需要按相反的顺序处理,那么您可以简单地使用
sequence
函数

out_1<- sequence(rle(out_2)$lengths)
cbind(out_1, out_2)
      out_1 out_2
 [1,]     1    -1
 [2,]     2    -1
 [3,]     1     1
 [4,]     1    -1
 [5,]     2    -1
 [6,]     3    -1
 [7,]     4    -1
 [8,]     5    -1
 [9,]     6    -1
out\u 1