Adrien
Adrien

Reputation: 151

Storing coefficient estimates for models with different coefficients

I am trying to store the coefficient estimates for different models. To illustrate my problem, Here is an Example below.

library(fpp)

creditlog <- data.frame(score=credit$score, 
  log.savings=log(credit$savings+1), 
  log.income=log(credit$income+1), 
  log.address=log(credit$time.address+1),
  log.employed=log(credit$time.employed+1)) 

fit_1 <-lm(score ~ log.income + log.address + log.employed , data=creditlog)
fit_2 <-lm(score ~ log.savings +  log.employed , data=creditlog)
fit_3 <-lm(score ~  log.address + log.employed , data=creditlog)
fit_4 <- lm(score ~  log.income + log.address , data=creditlog)


coef_1 <-summary(fit_1)$coef[,1]
coef_2 <-summary(fit_2)$coef[,1]
coef_3 <-summary(fit_3)$coef[,1]
coef_4 <-summary(fit_4)$coef[,1]
> coef_1
 (Intercept)   log.income  log.address log.employed 
  -14.957037    10.082396     3.353521     1.049130 
> coef_2
 (Intercept)  log.savings log.employed 
    24.34323     11.28698      1.92655 
> coef_3
 (Intercept)  log.address log.employed 
   26.115064     3.438382     1.213017 
> coef_4
(Intercept)  log.income log.address 
  -13.38037    10.23459     3.58023 

If I try rbind, I get

       (Intercept) log.income log.address log.employed
coef_1   -14.95704  10.082396    3.353521      1.04913
coef_2    24.34323  11.286978    1.926550     24.34323
coef_3    26.11506   3.438382    1.213017     26.11506
coef_4   -13.38037  10.234590    3.580230    -13.38037
Warning message:
In rbind(coef_1, coef_2, coef_3, coef_4) :
  number of columns of result is not a multiple of vector length (arg 2)
> 

which is not the right answer. What I need is something like,

     (Intercept)    log.savings  log.income  log.address    log.employed 
fit_1   -14.957037  NA           10.082396   3.353521       1.04913
fit_2   24.34323    11.28698     NA          NA             1.92655
fit_3   26.115064   NA           NA          3.438382       1.213017
fit_4   -13.38037   NA           10.23459    3.58023        NA

Thanks in advance.

Upvotes: 2

Views: 197

Answers (3)

eipi10
eipi10

Reputation: 93851

Here's a way to do it with a relatively short piece of code. It uses coef to directly extract the coefficients from the model object, and lapply to avoid repeating the same code for each model object. rbind.fill takes care of putting each coefficient value in the correct column:

library(plyr) # For the rbind.fill function

fits = rbind.fill(lapply(list(fit_1, fit_2, fit_3, fit_4), 
                  function(x) as.data.frame(t(coef(x)))))

fits
  (Intercept) log.income log.address log.employed log.savings
1   -14.95704   10.08240    3.353521     1.049130          NA
2    24.34323         NA          NA     1.926550    11.28698
3    26.11506         NA    3.438382     1.213017          NA
4   -13.38037   10.23459    3.580230           NA          NA

If you have a lot more than four model objects and don't want to type all of their names, you can reference the object names programmatically. For example, if you have model objects fit_1 through fit_20, then replace list(fit_1, fit_2, fit_3, fit_4) with mget(paste0("fit_", 1:20)). mget takes a vector of text strings and returns the objects with those names.

Upvotes: 1

rnso
rnso

Reputation: 24593

Following can be used using base R to combine lists with partial columns:

c1 = data.frame(a=1,b=2,d=3)
c2 = data.frame(b=2,c=3)
c3 = data.frame(a=4,d=5)

cc = data.frame(a=numeric(), b=numeric(), c=numeric(), d=numeric())
ff = function(vect, cc){
    n = nrow(cc)+1
    for(i in 1:length(vect)){
        cc[n,names(vect)[i]] = vect[i]
    }
    cc
}

cc=ff(c1, cc)
cc=ff(c2, cc)
cc=ff(c3, cc)
cc
   a  b  c  d
1  1  2 NA  3
2 NA  2  3 NA
3  4 NA NA  5

Upvotes: 0

Carlos Cinelli
Carlos Cinelli

Reputation: 11607

You can transform the vectors in data.frames and use dplyr's rbind_all:

library(dplyr)
# transforming in data.frames
coef_1 <- as.data.frame(t(summary(fit_1)$coef[,1]))
coef_2 <- as.data.frame(t(summary(fit_2)$coef[,1]))
coef_3 <- as.data.frame(t(summary(fit_3)$coef[,1]))
coef_4 <- as.data.frame(t(summary(fit_4)$coef[,1]))

# binding them all
coefs <- rbind_all(list(coef_1, coef_2, coef_3, coef_4))
row.names(coefs) <- c("fit_1", "fit_2", "fit_3", "fit_4")
coefs


      (Intercept) log.income log.address log.employed log.savings
fit_1   -14.95704   10.08240    3.353521     1.049130          NA
fit_2    24.34323         NA          NA     1.926550    11.28698
fit_3    26.11506         NA    3.438382     1.213017          NA
fit_4   -13.38037   10.23459    3.580230           NA          NA

Upvotes: 0

Related Questions