[R-sig-finance] tips and tricks for rolling regressions?

Ajay Shah ajayshah at mayin.org
Wed Aug 25 14:00:41 CEST 2004


On Wed, Aug 25, 2004 at 12:31:51PM +0100, Taher Khan wrote:
> Greetings!
> 
> I want to find out if there is a clever way to do a one-step-ahead
> moving window rolling regression using a vectorized operation like with
> apply, rather than a for loop.
> 
> Does anyone have a code snippet they would like to share for how they do
> rolling regressions?!?!

Version 1 : my low-quality hacked-up version -- but using simple
programming constructs that even a child can understand --

snip snip ------------------------------------------------------------
# Using moving windows, we do an OLS regression.
#
# The function returns a matrix with T rows. So there are plenty of
# "NA" values in it. The columns are organised as:
#    beta1 s1 beta2 s2 beta3 s3 sigma R^2
# i.e. we have each regression coefficient followed by it's sigma,
# and then at the end we have the residual sigma and the regression R^2.
#
# Example of usage -- to get moving window mean & sigma - 
#  r = movingWindowRegression(E, length(E$date), width, r.usd ~ 1, 1)
# WARNING: for the model, say 'r.usd~1', not 'E$r.usd~1'.
#
# Use the returned matrix like r[width:T,1] as the moving window mean etc.
movingWindowRegression <- function(data, T, width, model, K) {
  results = matrix(nrow=T, ncol=2*K+2)
  for (i in width:T) {
    details <- summary.lm(lm(model, data[(i-width+1):i,]))
    n=1;
    for (j in 1:K) {
      results[i, n:(n+1)]   = details$coefficients[j, 1:2]
      n = n + 2
    }
    results[i, n] = details$sigma
    results[i, n+1] = details$r.squared
  }
  return(results)
}
snip snip ------------------------------------------------------------






And from Douglas Bates (bates at stat.wisc.edu), a beautiful, brilliant
version, that is faster than mine, but that I only dimly understand --
see http://tolstoy.newcastle.edu.au/R/help/04/04/1269.html -- 

snip snip ------------------------------------------------------------
movingWindow2 <- function(formula, data, width, ...) {
    mCall = match.call()
    mCall$width = NULL
    mCall[[1]] = as.name("lm")
    mCall$x = mCall$y = TRUE
    bigfit = eval(mCall, parent.frame())
    ncoef = length(coef(bigfit))
    width = as.integer(width)[1]
    y = bigfit$y
    x = bigfit$x
    nr = nrow(x)
    stopifnot(width >= ncoef, width <= nr)
    terms = bigfit$terms
    inds = embed(seq(nr), width)[, rev(seq(width))]
    sumrys <- lapply(seq(nrow(inds)),
                     function(st) {
                         ind = inds[st,]
                         fit = lm.fit(x[ind, , drop = FALSE], y[ind])
                         fit$terms = terms
                         class(fit) = "lm"
                         summary(fit)
                     })
    list(coefficients = sapply(sumrys, function(sm) coef(sm)[,"Estimate"]),
         Std.Error = sapply(sumrys, function(sm) coef(sm)[,"Std. Error"]),
         sigma = sapply(sumrys, "[[", "sigma"),
         r.squared = sapply(sumrys, "[[", "r.squared"))
}
snip snip ------------------------------------------------------------

-- 
Ajay Shah                                                   Consultant
ajayshah at mayin.org                      Department of Economic Affairs
http://www.mayin.org/ajayshah           Ministry of Finance, New Delhi



More information about the R-sig-finance mailing list