plyr along two dimensions (ddply)

I have a data frame that looks like this (simplified for exposition):

date id value
d1 id1 v1
d2 id1 v2
d1 id2 v3
d2 id2 v4

I would like to break this apart by id, run a rolling regression on each id (so for each id there will be N regressions), pick out the rsquared and assemble this back to a dataframe. My method for doing this was:

roll_reg <- function(df) {
    T <- with(df, min(nlen(xs_ret), nlen(xs_mkt), nlen(smb), nlen(hml), nlen(umd)))
    OFFSET <- 3

    themodels <- as.list(rep(NA, OFFSET))
    #120 days rolling period
    if (T>OFFSET) {
        #the first OFFSET models are na

        for (i in seq(OFFSET+1, T)) {
            idx <- seq(i-OFFSET-1,i)
            themodels[i] <- list(with(df, 
                      lm(xs_ret[idx]~xs_mkt[idx]+smb[idx]+hml[idx]+umd[idx])))

        }

        return(themodels)
    }
    else { return(NA) }
}

models <- dlply(dt_df, "id", roll_reg)

Then I was going to reassemble everything using

ldply(models, function(x) {summary(x)$r.squared})

This does not work since models is a list of lists, and x is a list of models. However, if my function(x) returns a list by cat-ing all the rsquared into a list I get an error because ldply expects function(x) to return an atomic result. Help would be much appreciated.

Answers


This R code reproduces the problem:

library(plyr)

dat = data.frame(date = rep(paste("d", 1:100, sep = ""), length = 100),
             id = rep(paste("id", 1:10, sep = ""), each = 100),
             value = runif(100))

make.lm = function(input) {
  lm1 = lm(value~date, input[1:50,])
  lm2 = lm(value~date, input[1:50,])
  return(list(lm1, lm2))
}

models = dlply(dat, c("id"), make.lm)
coefs = ldply(models, function(x) summary(x)$r.squared)
# Error in summary(x)$r.squared : $ operator is invalid for atomic vectors

This works:

models = dlply(dat, c("id"), make.lm)
coefs = ldply(models, function(x) 
             ldply(x, function(y) 
              return(data.frame(rsq = summary(y)$r.squared))))
coefs$id2 = rep(1:2, each = 2)

> head(coefs)
    id rsq id2
1  id1   1   1
2  id1   1   1
3 id10   1   2
4 id10   1   2
5  id2   1   1
6  id2   1   1

Hope this answers your question.


Need Your Help

Cocos2D magnification - making the code dynamic and using an image

ios cocos2d-iphone magnification magnify

I have found the following code and I need help with editing it. I am not really familiar with texture rendering.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.