I would like to calculate the sum of a variable from t-12 to t-1 within a data.frame using base R. For example, in the code below I am trying to calculate the sum of HOURS from MONTH t-12 to MONTH t-1 (by NAME). Any help is greatly appreciated.
DF <- data.frame(c(expand.grid(NAME = c("Frank", "Tony", "Edward"), YEAR = c(2014:2015), MONTH = c(1:12))), HOURS = rnorm(72))
DF <- DF[with(DF, order(NAME, YEAR, MONTH)), ]
DF
DF <- within(DF, WORK <- sum(c(rep(NA, 1), head(HOURS, -1)):c(rep(NA, 12), head(HOURS, -12))))
Here's a base R approach (at least in terms of not using dplyr
for grouping or chaining, but still using a package for the rolling sum). I used the zoo
package's rollsum
function, but, per @jeremycg's answer, you can use roll_sum
from RcppRoll
as well. If you don't even want to use a package for the rolling sum, you can roll your own function (no pun intended) if you wish.
library(zoo)
DF = DF[order(DF$NAME, DF$YEAR, DF$MONTH),]
DF$sum = unlist(lapply(unique(DF$NAME), function(x) {
c(NA, rollsum(DF$HOURS[DF$NAME==x], 12, na.pad=TRUE, align="right")[-length(DF$NAME[DF$NAME==x])])
}))