0

I'm running into issues while applying a moving window function to a time series dataset. I've imported daily streamflow data (date and value) into a zoo object, as approximated by the following:

library(zoo)
df <-  data.frame(sf = c("2001-04-01", "2001-04-02", "2001-04-03", "2001-04-04", 
                         "2001-04-05", "2001-04-06", "2001-04-07", "2001-06-01", 
                         "2001-06-02", "2001-06-03", "2001-06-04", "2001-06-05", 
                         "2001-06-06"), 
                      cfs = abs(rnorm(13)))
zoodf <- read.zoo(df, format = "%Y-%m-%d")

Since I want to calculate the 3-day moving minimum for each month I've defined a function using rollapply:

f.3daylow <- function(x){rollapply(x, 3, FUN=min, align = "center")}

I then use aggregate:

aggregate(zoodf, by=as.yearmon, FUN=f.3daylow)

This promptly returns an error message:

Error in zoo(df, ix[!is.na(ix)]) : 
  “x” : attempt to define invalid zoo object

The problem appears to be that there are unequal number of data points in each month,since using the same dataframe with an additional date for June results in a correct response. Any suggestions for how to deal with this would be appreciated!

Jaywalker
  • 49
  • 5
  • What exactly do you want it to output? At the moment it uses the function on either year+month combination, and does the function over all the elements in that set, and will output one value for each set. If you just want the minimum, you don't need a complex rollapply function. – puslet88 Mar 11 '15 at 21:21
  • For each month there should be multiple values corresponding to the results of each 3-day moving window minimum; i.e., April 2001 0.1 0.1 0.2...; May 2001 0.2 0.1 0.3... – Jaywalker Mar 11 '15 at 22:53

1 Answers1

2

Ok, you might be thinking of something like this then. It pastes the results for each month into one data point, so that it can be returned in the aggregate function. Otherwise you may also have a look at ?aggregate.zoo for some more precise data manipulations.

f.3daylow <- function(x){paste(rollapply(x, 3, FUN=min, 
               align = "center"),  collapse=", ")}

data <- aggregate(zoodf, by=as.yearmon, FUN=f.3daylow)

Returns, this is then a rolling window of 3 copied into 1 data point. To analyse it, eventually you will have to break it down again, so it is not recommended.

Apr 2001 
0.124581285281643, 0.124581285281643, 0.124581285281643,
0.342222172241979, 0.518874882033892 
June 2001 
0.454158221843514, 0.454158221843514, 0.656966528249837,
0.513613009234435 

Eventually you can cut it up again via strsplit(data[1],", "), but see Convert comma separated entry to columns for more details.

Community
  • 1
  • 1
puslet88
  • 1,288
  • 15
  • 25