# Developers Planet

qdwu February 2016

### Problems with control statement if...else in R

I am a beginner in R and here's my code:

``````for (i in 1:7){
testing<-vector(length=(length(yy)-3))
if(all(yy[i:(i+2)]==0))
testing[i]<-1
else
testing[i]<-NA
}
``````

`yy` refers to the following vector of length 10:

``````> yy
[1] 1 0 0 0 0 1 0 1 0 1
``````

`testing` is like a predict function output, which will predict a 1 if the previous 3 elements in `yy` are all 0.If not, it will not predict anything, and so NA. Since `yy` has a total of 10 elements, `testing` will have a total of 7 elements (Therefore length 7) However, instead of giving me a output of 1s and NAs, it is giving this:

``````> testing
[1] FALSE FALSE FALSE FALSE FALSE FALSE    NA
``````

I cannot figure out why, some help will be great. Thank you.

DatamineR February 2016

You should define `testing` outside the loop:

``````testing<-vector(length=(length(yy)-3))
for (i in 1:7){
if(all(yy[i:(i+2)]==0))
testing[i]<-1
else
testing[i]<-NA
}

testing
[1] NA  1  1 NA NA NA NA
``````

For this task you couls also use `rollapply` from `zoo`:

``````library(zoo)
rollapply(yy, 3, function(x) ifelse(all(x == 0), 1, NA))
[1] NA  1  1 NA NA NA NA NA
``````

David Arenburg February 2016

Here are some additional vectorized ways of solving this

Base r `stats::filter`

``````N <- 3
NA^(stats::filter(yy == 0, rep(1, N), sides = 1)[-(1:N-1)] != N)
# [1] NA  1  1 NA NA NA NA NA
``````

`data.table::shift`

``````NA^(Reduce(`+`, data.table::shift(yy == 0, 0:(N-1)))[-(1:N-1)] != N)
# [1] NA  1  1 NA NA NA NA NA
``````

`RcppRoll::roll_sum`

``````NA^(RcppRoll::roll_sum(yy == 0, N) != N)
# [1] NA  1  1 NA NA NA NA NA
``````

Some becnmarks (I've also added a compiled version of the for loop using `compiler::cmpfun` and two more efficient `zoo` solutions)

``````ForLoop <- function(yy, N){
testing<-vector(length=(length(yy)-N))
for (i in 1:length(testing)){
if(all(yy[i:(i+(N-1))]==0))
testing[i]<-1
else
testing[i]<-NA
}
testing
}

ForLoopBin <- compiler::cmpfun(ForLoop)

ZOO <- function(yy, N) zoo::rollapply(yy, N, function(x) ifelse(all(x == 0), 1, NA))

ZOO2 <- function(yy, N) NA^!zoo::rollapply(yy == 0, N, all)

ZOO3 <- function(yy, N) NA^(zoo::rollsum(yy == 0, N) != N)

RCPPROLL <- function(yy, N) NA^(RcppRoll::roll_sum(yy == 0, N) != N)

BaseFilter <- function(yy, N) NA^(stats::filter(yy == 0, rep(1, N), sides = 1)[-(1:N-1)] != N)

DTShift <- function(yy, N) NA^(Reduce(`+`, data.table::shift(yy == 0, 0:(N-1)))[-(1:N-1)] != N)

set.seed(123)
yy <- sample(0:1, 1e4, replace = TRUE)
N <- 3

library(microbenchmark)
microbenchmark(
"for loop" = ForLoop(yy, N),
"Compiled for loop" = ForLoopBin(yy, N),
"zoo1" = ZOO(yy, N),
"zoo2" = ZOO2(yy, N),
"zoo3" = ZOO3(yy, N),
"Rcpproll" = RCPPROLL(yy, N),
"stats::filter" = BaseFilter(yy, N),
"data.table::shift" = DTShift(yy, N)
)

# Unit: microseconds
#              expr        min         lq        mean      median          uq        max neval    cld
#          for loop  25917.837  26858
``````
``` ```
``` ```
``` ```
``` ```
``` ```
``` Post Status Asked in February 2016Viewed 1,426 timesVoted 5Answered 2 times Search Leave an answer ```
``` ```
``` ```
``` Quote of the day: live life .btn-primary{ background-color: #f44336 !important; border-color: #f44336 !important; } Devs Planet ® 2014-2016 www.devsplanet.com Devs Planet © all rights reserved Quick Actions Search // Used to toggle the menu on small screens when clicking on the menu button function myFunction() { var x = document.getElementById("navDemo"); if (x.className.indexOf("w3-show") == -1) { x.className += " w3-show"; } else { x.className = x.className.replace(" w3-show", ""); } } ```