1

I have a vector of integers x <- c(5, 5, 4, 4, 4, 8, 8, 8, 8, 5, 5, 9, 4, 4, 5, 5) and want to create a new vector of the same length. This new vector starts from 1 and the value stays the same if the value in x doesn't change from the previous one; the value should increase by 1 as long as there is a change in x. So the desired result is 1 1 2 2 2 3 3 3 3 4 4 5 6 6 7 7. In other words, the result is the label for the runs in x.

What I have now is a for loop as below. But I wonder if there are some functions or a vectorized way of doing this.

x <- c(5, 5, 4, 4, 4, 8, 8, 8, 8, 5, 5, 9, 4, 4, 5, 5)
n <- length(x)
y <- rep(NA, n)
y[1] <- 1
for (i in 2:n) {
  if (x[i] == x[i - 1]) {
    y[i] <- y[i - 1]
  }
  else {
    y[i] <- y[i - 1] + 1
  }
}
> y
 [1] 1 1 2 2 2 3 3 3 3 4 4 5 6 6 7 7
JACKY88
  • 3,391
  • 5
  • 32
  • 48

2 Answers2

1
tmp=rle(x)
rep(seq_along(tmp$values),tmp$lengths)
[1] 1 1 2 2 2 3 3 3 3 4 4 5 6 6 7 7
user2974951
  • 9,535
  • 1
  • 17
  • 24
1

One option could be:

cumsum(c(0, diff(x)) != 0) + 1

 [1] 1 1 2 2 2 3 3 3 3 4 4 5 6 6 7 7
tmfmnk
  • 38,881
  • 4
  • 47
  • 67