Search code examples
rzoorollapply

Count observations using rollapply from zoo package with dynamic criteria


I am looking for a way to count observations like here but with the ability to change criteria according to the specific observation (moving count).

For example - count the number of observations of mag (from the last 50) which are greater than the specific observation of mag. The code I have:

rollapplyr(zoo(mag),50,function(i){sum(mag>i)},partial=T,by.column=F,fill=NA))

This code takes the average mag of the 50 last observations and calculates the number of observations above that average (in the whole data-set).

What am I missing ? Maybe using rollapply is not the case here ? To sum it up:
1. count according to specific row value
2. count only in the 50 last observations (and not the whole data-column).


Solution

  • Please see the "corrected" function below:

    set.seed(2017)
    mag <- sample(x = 1000, size = 20)
    
    ## Your function, see what is printed
    # my_fun <- function(i) {
    #   print(i)
    #   print(mag)
    #   sum(mag > i)
    # }
    
    ## Corrected one
    my_fun <- function(i) {
      print(i)
      print(tail(i, 1))
      sum(i > tail(i, 1))
    }
    
    # debug(my_fun)  # Play a little with debug(), it is worth it!
    
    mag_out <- zoo::rollapplyr(
      # zoo::zoo(mag),
      mag,
      5,
      my_fun,
      partial = TRUE,
      by.column = FALSE,
      fill = NA
    )
    
    rbind(
      mag,
      mag_out
    )
    

    Output:

            [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20]
    mag      244  329  987  833  524  112  869  327  488   691    89   224   206    73   803   868   288   365   666   145
    mag_out    0    0    0    1    2    4    1    3    2     1     4     3     3     4     0     0     2     2     2     4