Calculate rolling means or sums on time-series data.
setwd("~/FESA/playground/met/daily_1986-2003")
load("07_workspace.RData")
# daily rainfall
rain.mean <- aggregate(x = daily$Rain_mm_total, by = list(daily$Date), FUN = mean,
na.rm = TRUE)
# create a fixed character index from dates. check ?strptime for details
# make sure the new index is unique for the time-frames in question
daily$MyMonth <- paste(format(daily$Date, "%Y"), format(daily$Date, "%m"))
head(daily$MyMonth)
## [1] "1986 01" "1986 01" "1986 01" "1986 01" "1986 01" "1986 01"
daily$MyDay <- paste(format(daily$Date, "%Y"), format(daily$Date, "%j"))
head(daily$MyDay)
## [1] "1986 001" "1986 002" "1986 003" "1986 004" "1986 005" "1986 006"
# then use the new index in a aggregate or plyr function to do the
# aggregation
# load the 'zoo' library ('z-ordered objects')
library(zoo)
##
## Attaching package: 'zoo'
##
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
# Rolling means/sums, etc... functions are provided convert rain.mean to a
# time series object
z.rain.mean <- read.zoo(rain.mean)
# calculate rolling mean/median
# rollmedian(z.rain.mean, 91, align = 'left')
# calculate rolling sum
mov.rain90 <- rollapply(z.rain.mean, 90, sum, align = "left", partial = TRUE)
# convert back to data frames
mov.rain90 <- as.data.frame(mov.rain90)
mov.rain90$Date <- rownames(mov.rain90)
mov.rain90$Date <- as.POSIXct(mov.rain90$Date, tz = "Australia/Melbourne")
A quick remark on rounding to a specific integer. Just in case the usual round, ceiling, or floor is not sufficient to create your index
# round a number to the chosen threshold - from the plyr library:
library(plyr)
x <- c(-8, 1, 2, 3, 4, 5, 6, 35, 66)
# round to nearest number in steps of 5
round_any(x, accuracy = 5)
## [1] -10 0 0 5 5 5 5 35 65
round_any(x, 7)
## [1] -7 0 0 0 7 7 7 35 63
round_any(x, 100)
## [1] 0 0 0 0 0 0 0 0 100
# watch out for negative numbers:
round_any(x, -3)
## [1] -9 0 3 3 3 6 6 36 66
round_any(x, 3)
## [1] -9 0 3 3 3 6 6 36 66