Search code examples
tidyversezoorollapply

Apply rolling function to one column using zoo::rollapply in dplyr::mutate


I want to apply a rolling function to a vector in a data frame, specifically, to take the difference between a single column for every 10 observations. For example, to get the difference in Sepal.Lengths from the iris dataset, I tried the following:

data <- data(iris)

data1 <- data %>%
  mutate(length_Change = zoo::rollapply(Sepal.Length, 
                                   width = 10, 
                                   FUN = function(x){max(x, na.rm = T)-min(x, na.rm = T)}, 
                                   align = "right", 
                                   by.column = FALSE))

but I got the following error:

Error in `mutate()`:
ℹ In argument: `length_Change = rollapply(...)`.
Caused by error:
! `length_Change` must be size 150 or 1, not 141.

and I can't figure out why this isn't working. Any ideas?

Thanks!


Solution

  • The issue is that the size of your window is 10, the number of rows in iris is 150, and (by default) partial = FALSE, so once it hits the 141st row, and there's only 9 available rows remaining in the dataframe, so it stops there (i.e. it doesn't run on a partial window), hence you getting 141 rows.

    To get it working, set partial = TRUE.

    For more information, read the documentation.