Count consecutive elements in a same length vector

被刻印的时光 ゝ 提交于 2019-12-29 01:37:08

问题


If I have a vector like

"a": 0 0 1 1 1 0 0 0 0 1 1 0 0 0

How can I generate a vector of the same length containing the count of consecutive elements, like so:

"b": 2 2 3 3 3 4 4 4 4 2 2 3 3 3

I tried rle, but I did not manage to stretch it out this way.


回答1:


Another option using rle and rep

with(rle(a), rep(lengths, times = lengths))
# [1] 2 2 3 3 3 4 4 4 4 2 2 3 3 3

data

a <- c(0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0)



回答2:


Create a grouping variable using diff and use it in ave to calculate length of each group.

ave(x, cumsum(c(0, diff(x) != 0)), FUN = length)
# [1] 2 2 3 3 3 4 4 4 4 2 2 3 3 3

You can do the same with dplyr lag

library(dplyr)       
ave(x,cumsum(x != lag(x, default = FALSE)), FUN = length)
#[1] 2 2 3 3 3 4 4 4 4 2 2 3 3 3

And for completeness with data.table rleid

library(data.table)
ave(x, rleid(x), FUN = length)
#[1] 2 2 3 3 3 4 4 4 4 2 2 3 3 3

data

x <- c(0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0)



回答3:


Here is another solution using vapply

count_consec <- function (a) {
  # creating output vector out
  out <- integer(length(a))

  # consecutive differences
  diffs <- which(diff(a) != 0)

  # returning 0 just in order to have a return statement in vapply - you can return anything else
  vapply(1:(length(diffs)+1), function (k) {
    if (k == 1) {
      out[1:diffs[1]] <<- diffs[1]
      return (0L)
    }
    if (k == length(diffs)+1) {
      out[(diffs[k-1]+1):length(out)] <<- length(out) - diffs[k-1]
      return (0L)
    }
    out[(diffs[k-1]+1):diffs[k]] <<- diffs[k] - diffs[k-1]
    return (0L)
  }, integer(1))
  out
}
count_consec(a)
# [1] 2 2 3 3 3 4 4 4 4 2 2 3 3 3

with the data a <- as.integer(unlist(strsplit('0 0 1 1 1 0 0 0 0 1 1 0 0 0', ' ')))



来源:https://stackoverflow.com/questions/54072409/count-consecutive-elements-in-a-same-length-vector

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!