Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to combine a list of unequal lm object length into a data frame?

I like to extract the coefficients and standard errors of each lm object and combine them into a data.frame with NA fill in for the missing predictors.

    set.seed(12345)
    x<-matrix(rnorm(1000),nrow=100,ncol=10)
    colnames(x)<-paste("x",1:10,sep="")
    df<-data.frame(y=rnorm(100),x)
    m1<-vector('list', 10)
    for ( i in 2:11){
    eqn <- as.formula(paste("y ~", paste(colnames(df)[2:i], collapse='+')))
    m1[[i-1]] <- lm(eqn, df)
    }

Any suggestions would be much appreciated!

like image 485
Tony Avatar asked Dec 27 '22 02:12

Tony


2 Answers

This should do the trick:

cList <- lapply(m1, coef)
nms  <- names(cList[[11]])

cMat <- do.call(rbind, lapply(cList, function(X) X[nms]))
cDF  <- as.data.frame(cMat); names(cDF) <- nms   # Pretty up the results

cDF[1:5, 1:6]
#   (Intercept)        x1          x2         x3         x4       x5
# 1  -0.2345084 0.2027485          NA         NA         NA       NA
# 2  -0.2334043 0.2074812 -0.05006297         NA         NA       NA
# 3  -0.2299977 0.2099620 -0.03892985 0.09777829         NA       NA
# 4  -0.2095798 0.2221179 -0.02710201 0.06403695 -0.1184191       NA
# 5  -0.2060406 0.2180674 -0.01062671 0.06632922 -0.1045128 0.130937

Edit:

To collect the standard errors into a similar structure, just do something like this:

seList <- lapply(m1, function(X)  coef(summary(X))[,2])
seMat <- do.call(rbind, lapply(cList, function(X) X[nms]))
seDF  <- as.data.frame(cMat); names(seDF) <- nms
like image 55
Josh O'Brien Avatar answered Jan 15 '23 12:01

Josh O'Brien


Here is an approach using merge and Reduce:

m2 <- lapply(m1[-1], function(x) as.data.frame(coef(summary(x))) )

tmpfun <- function(x,y) {
    n <- as.character(nrow(y)-1)
    xn <- if( 'Row.names' %in% colnames(x) ) 1 else 0
    merge(x,y,by.x=xn, by.y=0, suffixes=c('',n), all=TRUE)
}

out <- Reduce(tmpfun, m2)

You may want to reorder the columns, or drop some of the columns in m2, or transpose the result.

like image 40
Greg Snow Avatar answered Jan 15 '23 11:01

Greg Snow