【问题标题】:Increment values in vector conditionally (conditional restarting running sum)-- vectorized version?有条件地增加向量中的值(有条件地重新启动运行总和)——向量化版本?
【发布时间】:2017-08-21 21:09:07
【问题描述】:

给定一个二进制值向量out_2,下面的代码返回一个向量 与out_2 的长度相同,称为out_1out_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_2 获取 out_1(即矢量化显式 for 循环)?

【问题讨论】:

    标签: r vectorization


    【解决方案1】:

    我会使用来自基础Rrle。棘手的部分是得到out_1 向量的相反顺序,所以它有(?)通过`lapply'

    out_1<- unlist(lapply(rle(out_2)$lengths, function(x) seq(x, by=-1)))
    

    结果是:

    cbind(out_1, out_2)
          out_1 out_2
     [1,]     2    -1
     [2,]     1    -1
     [3,]     1     1
     [4,]     6    -1
     [5,]     5    -1
     [6,]     4    -1
     [7,]     3    -1
     [8,]     2    -1
     [9,]     1    -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
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-04
        • 1970-01-01
        相关资源
        最近更新 更多