Search code examples
rzooglmnet

R rollapply on glmnet


library(zoo)
library(glmnet)

I can get the rolling coefficients on a linear regression:

seat <- as.zoo(log(UKDriverDeaths))
time(seat) <- as.yearmon(time(seat))
seat <- merge(y = seat, y1 = lag(seat, k = -1),
y12 = lag(seat, k = -12), all = FALSE)



tail(seat)
fm <- rollapply(seat, width = 50,
FUN = function(z) coef(lm(y ~ y1 + y12, data = as.data.frame(z))),
by.column = FALSE, align = "right")

but I am having trouble getting the rolling coefficients for glmnet:

fm <- rollapply(seat, width = 50,
FUN = function(z) coef(cv.glmnet(z[,c(2,3)],z[,1],alpha=1, data = 
as.data.frame(z))), by.column = FALSE, align = "right")

Thank you for any help


Solution

  • First, cv.glmnet doesn't have a data argument. It has x and y arguments which are the predictor matrix and response vector respectively.

    Second, your seat dataset has missing values in the first row (unavoidable due to the lag operation). This will mess up glmnet, which has a rather bare-bones interface which does minimal checking.

    Third, coef on a glmnet/cv.glmnet object returns a sparse matrix, which rollapply doesn't know what to do with.

    Fixing all of these gives:

    fm2 <- rollapply(seat, width=50, FUN=function(z)
    {
        z <- na.omit(z)
        as.numeric(coef(cv.glmnet(z[, c(2, 3)], z[, 1], alpha=1)))
    }, by.column=FALSE, align="right")
    

    You can also use my glmnetUtils package, which implements a formula/data frame interface to glmnet. This deals with the first two problems above.

    library(glmnetUtils)
    fm3 <- rollapply(seat, width=50, FUN=function(z)
    {
        as.numeric(coef(cv.glmnet(y ~ y1 + y12, data=as.data.frame(z), alpha=1)))
    }, by.column=FALSE, align="right")