Reputation: 240
I wonder how to write some simple code to solve this problem: Question like this,I got a vector like this:
x <- c(0,1,0,0,1,0,0,0,0,1,0)
while I want to do some computing and then get y:
y <- c(0,1,1,1,1,1,0,0,1,1)
The rule is : If you find one '1',then substitue the following 2 zeros as '1'.
Upvotes: 1
Views: 84
Reputation: 887153
Here is another approach with shift
from data.table
. The shift
can take n
as a vector to get a list
of lag
(by default), Reduce
it to a vector
by adding (+
) the corresponding elements of the list
, convert to a logical vector (> 0
- here it works without doing this) and convert to binary with +
.
library(data.table)
+(Reduce(`+`, shift(x, 0:2, fill=0)) > 0)
#[1] 0 1 1 1 1 1 1 0 0 1 1
Or
sign(Reduce(`+`, shift(x, 0:2, fill=0)))
Upvotes: 1
Reputation: 263352
This approach uses pmax on shifted versions of the x-vector:
pmax ( x, c(NA,head(x,-1)) , c(NA,NA,head(x,-2)) , na.rm=TRUE)
[1] 0 1 1 1 1 1 1 0 0 1 1
Upvotes: 2
Reputation: 1966
Another solution:
sign(Reduce(function(x,y) min(3, max(x-1,0) + y), 3*x, acc=T))
This Reduce()
effectively creates a counter which decrements by 1 in the case of 0, and resets to 3 in the case of 1. Taking the sign()
gives the desired result.
Upvotes: 2
Reputation: 73315
We may use
id <- rep(which(diff(x) == -1), each = 2) + 1:2
x[id[id <= length(x)]] <- 1
tmp <- which(diff(x) == -1)
gives positions of 1
followed by 0
;id <- rep(tmp, each = 2) + 1:2
identifies the following 2 positions;x[id] <- 1
, but this may create a longer vector when x
has 1
around the end. So we bound it by: x[id[id <= length(x)]] <- 1
.Upvotes: 3