I didn't consider the end effects carefully, but given your initial example,
I didn't worry about it. Here is a modified version:

f <- function(x, n) {
   r <- rle(x)
   # Sequence of start indices for zero replacement
   t1 <- cumsum(r$lengths)[r$values == 0L] + 1
  # Get rid of last element if sequence ends in zero
   t1 <- t1[t1 <= length(x)]
   # run lengths of ones
   nOnes <- with(r, lengths[values == 1L])
   # remove the first if the sequence starts with 1
   if(r$values[1] == 1L) nOnes <- nOnes[-1]
   # second term in sum takes the parallel minimum
   # of run lengths of ones and the value 2
   t2 <- t1 + pmin(nOnes - 1, 2)
   # create vector of indices for zero replacement
   repl <- as.vector(mapply(seq, t1, t1 + n - 1))
   replace(x, repl, 0)
  }

A test:

x <- rbinom(50, 1, 0.7)
rle(x)
Run Length Encoding
  lengths: int [1:27] 2 1 3 2 2 1 2 1 4 1 ...
  values : num [1:27] 1 0 1 0 1 0 1 0 1 0 ...
> rle(x)$lengths
 [1] 2 1 3 2 2 1 2 1 4 1 2 2 2 2 1 1 1 1 8 1 2 1 2 1 1 1 2
rle(x)$lengths[rle(x)$values == 1L]
 [1] 2 3 2 2 4 2 2 1 1 8 2 2 1 2

# I assume that no leading ones are replaced because there is no preceding
zero
> f(x, 3)
 [1] 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
1 1
[39] 1 0 0 0 0 0 0 0 0 0 0 0 0
> x
 [1] 1 1 0 1 1 1 0 0 1 1 0 1 1 0 1 1 1 1 0 1 1 0 0 1 1 0 0 1 0 1 0 1 1 1 1 1
1 1
[39] 1 0 1 1 0 1 1 0 1 0 1 1

Since only two run lengths of 1 after the initial one have a length greater
than three, this is fairly easy to verify. It seems to work.

system.time(f(sample(0:1, 1000000, replace = TRUE) , 3))
   user  system elapsed
   6.59    0.03    6.63

shows that it is not as fast as the regex method from stackoverflow that you
cited, which makes sense since it entails more overhead in checking the
propriety of the indices to replace. regex has more efficent ways of
handling text replacement.

Dennis





On Fri, Sep 10, 2010 at 12:43 PM, skan <juanp...@gmail.com> wrote:

>
> Hello, Dennis
>
> Do you prefer your way or this one?
>
> http://stackoverflow.com/questions/3686982/r-adding-zeroes-after-old-zeroes-in-a-vector
> stackoverflow, Jonathan
> <quote rr <- rle(tmp)
> ## Pad so that it always begins with 1 and ends with 1
> if (rr$values[1] == 0) {
>   rr$values <- c(1, rr$values)
>   rr$lengths <- c(0, rr$lengths)
> }
> if (rr$values[length(rr$values)] == 0) {
>  rr$values <- c(rr$values, 1)
>  rr$lengths <- c(rr$lengths, 0)
> }
> zero.indices <- seq(from=2, to=length(rr$values), by=2)
> one.indices <- seq(from=3, to=length(rr$values), by=2)
> rr$lengths[zero.indices] <- rr$lengths[zero.indices] +
> pmin(rr$lengths[one.indices], n)
> rr$lengths[one.indices] <- pmax(0, rr$lengths[one.indices] - n)
> inverse.rle(rr)
>
>
>
> --
> View this message in context:
> http://r.789695.n4.nabble.com/adding-zeroes-after-old-zeroes-in-a-vector-tp2534824p2534995.html
> Sent from the R help mailing list archive at Nabble.com.
>
> ______________________________________________
> R-help@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
> http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>

        [[alternative HTML version deleted]]

______________________________________________
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

Reply via email to