I have a vector of 0s and 1s and want to identify the indices where a string of 0s is surrounded by 1s. If the number of 0s between the 1s is lower or equal than 5, I want to change these zeros to 1s.
Here is an example:
> x <- c(0,0,0,1,1,1,0,0,0,1,1,0,0,0,0,0,0,1,1,1,1)
In positions 7,8, and 9, I have only three zeros, and thus these need to be changed to 1. The other zeros are more than 5, and thus need not to be changed.
The resulting vector should look like this:
> x_converted <- c(0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1)
I am doing this with a for loop and if else statement, but I am sure there must be a faster way to do this.
Thank you.
>Solution :
A possible solution with rle which does not change shorts sequences of zero’s at the beginning or end of x:
# create the run length encoding
r <- rle(x)
# create the index
i <- r$values == 0 & r$lengths < 5 &
c(tail(r$values, -1) == 1, FALSE) &
c(FALSE, head(r$values, -1) == 1)
# set the appropriate values to 1
r$values[i] <- 1
# use the inverse of rle to recreate the vector
inverse.rle(r)
which gives:
[1] 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1