chunjin
chunjin

Reputation: 240

Set the subsequent two 0 after every 1 in a binary vector to 1

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

Answers (4)

akrun
akrun

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

IRTFM
IRTFM

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

sirallen
sirallen

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

Zheyuan Li
Zheyuan Li

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;
  • basically we want 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

Related Questions