Search code examples
rzoorollapply

Unexpected output from rollapply due to zero length output from the function


I'm encountering a problem that I'm failling to understand. Here is the commented code :

library(zoo)
#Pattern p used as row feeding matrix to apply() for function f
> p
     [,1] [,2] [,3]
[1,]   -1    1    1
[2,]    1    1    1

#Function f supposed to take rows of matrix p as vectors,
#compare them with vector x and return index
f <- function(x) {  # identifies which row of `patterns` matches sign(x)
  which(apply(p,1,function(row)all(row==sign(x))))
}

#rollapplying f over c(1,-1,1,1) : there is no vector c(1,-1,1) in p
#so why the first atom is 1 ?
> rollapply(c(1,-1,1,1),width=3,f,align="left")
[1] 1 1

#rollapply identity, rollapply is supposed to feed row to the function right ?
> t = rollapply(c(1,-1,1,1),width=3,function(x)x,align="left")
     [,1] [,2] [,3]
[1,]    1   -1    1
[2,]   -1    1    1

#Feeding the first row of the precedent matrix to f is giving the expected result
> f(t[1,])
integer(0)

#rollapply feeds the rolls to the function
> rollapply(c(1,-1,1,1),width=3,function(x) paste(x,collapse=","),align="left")
[1] "1,-1,1" "-1,1,1"

#rollapply feeds vectors to the function
> rollapply(c(1,-1,1,1),width=3,function(x) is.vector(x),align="left")
[1] TRUE TRUE

#Unconsistent with the 2 precedent results
> f(c(1,-1,1))
integer(0)

Basically I don't understand why rollapply(c(1,-1,1,1),width=3,f,align="left") is returning 1 1 when the first roll from rollapply is supposed to yield the vector 1 -1 1 that is absent from the pattern matrix p. I was expecting the result NA 1 instead. There must be something I don't understand about rollapply but strangely enough if I feed the vector c(-1, -1, -1 ,-1) to rollapply I get the expected result NA NA. In some cases I have a mix 1 2 but never a mix NA 1 or NA 2.


Solution

  • According to G. Grothendieck rollapply does not support functions producing zero length outputs. It is possible to get rid of the problem by adding a condition in the function f returning a specific output in case it was returning zero length output.

      f <- function(x) {  # identifies which row of `patterns` matches sign(x)
        t <- which(apply(patterns,1,function(row)all(row==sign(x))))
        ifelse(length(t)==0, return(0), return(t))
      }