user189035 - 2 months ago 10

R Question

Given a vector of binary values

`out_2`

of same length as

`out_2`

`out_1`

The entries of

`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)

I was wondering if there is a one liner vectorized way to get

`out_1`

`out_2`

Answer Source

I would use `rle`

from base `R`

. The tricky part is to get the reverse order for the `out_1`

vector, so it has (?) to go through `lapply'

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

And the result is:

```
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
```

If you're flexible with the output and you don't need it to be in reverse order, you can simply use the `sequence`

function.

```
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
```