Vectorize thinking

164 Views Asked by At

I'm having a vectorization problem. Say I'm having a vector x <- c(0,0,1,0,1,1,0) , what I want is to get the vector (1,0,1,1), or to remove all the 0s from the first spot to the first non-zero spot and all the 0s from last non-zero spot to the last spot. It is easy in normal ways, but the tricky part is I cannot use any loops (for, while, etc). Basically, I must "vectorize" the whole algorithm. Anyone help please?

2

There are 2 best solutions below

4
On BEST ANSWER

I think you can try this, Thanks for @JacobH comment, this will be faster.

x <- c(0,0,1,0,1,1,0)
zeros <- which(x > 0)

x[zeros[1]:tail(zeros, n = 1)]

the output

[1] 1 0 1 1

5
On

Well, if speed is a concern, just use loops:

x <- rpois(1e8,1)
# Zihu Guo & JacobH's answer
system.time({zeros <- which(x > 0); x[zeros[1]:tail(zeros, n = 1)]})
#    user  system elapsed 
#    1.46    0.42    1.89 

# a slightly improved version of their answer
system.time({zeros <- which(!!x); x[zeros[1]:tail(zeros, n = 1)]})
#    user  system elapsed 
#    1.21    0.42    1.64 


system.time({
    lo  = 0L
    lov = 0L
    while (!lov){ lo = lo+1L ; lov = lov+x[lo] }
    hi  = length(x)+1L
    hiv = 0L
    while (!hiv){ hi = hi-1L ; hiv = hiv+x[hi] }    
    x[lo:hi]
})
#    user  system elapsed 
#    0.62    0.07    0.71 

Besides speed, this is nice because it requires no real knowledge of R. It could be made faster with the Rcpp package, probably.

(If the whole vector is zeros, this will never terminate. Small adjustments can be made if that matters. If the vector is mostly zeros, the which method is faster. For example, consider x <- rep(0L,1e8); x[1e8/2] <- 1L.)