Reputation: 325
I have some unruly data which I have tried to model with a number of varying linear models, which I have given various names. I then created a data frame called "compared fits". I am able to store some of the more relevant output from the various models using the code below.
for(i in 1:length(regressionmodels.listed))
{
comparedfits[i, 2] = summary(regressionmodels.listed[[i]])$df[2]
comparedfits[i, 3] = summary(regressionmodels.listed[[i]])$r.squared
comparedfits[i, 4] = summary(modelnow)$adj.r.squared
#See code snippet below for explanation
#name = deparse(get(substitute(regressionmodels.listed[[i]])))
#names_models[i] = name
}
The "regression models listed" is an object of type list which I create using simply:
regressionmodels.listed <- list(fit1, fit2 ...etc)
What I cannot do in any kind of iterative way is the following:
for(i in 1:length(regressionmodels.listed))
{
namesofmodels[i] = deparse(substitute(regressionmodels.listed[[i]]))
}
Note that if I run the deparse code on an individual fitted model, say fit1, it does work. I only cannot get it to work with the elements of a list of fitted models. This is obviously a "nice to have" kind of thing, but since I will be comparing maybe 10 or more models, it would really make my life easier if I could find a way to do this and add it to my other data frame above.
EDIT This is what the regressionmodels.listed looks like:
regressionmodels.listed <- list(lmobject1, lmobject2, lmobject3)
The lm objects are created simply by running a linear model on various combinations of the data.
Upvotes: 1
Views: 1384
Reputation: 46888
Your list of models are not named so there's no way of getting back "lmobject1" etc, one way is to name them at the start:
regressionmodels.listed <- list(lmobject1, lmobject2, lmobject3)
names(regressionmodels.listed) = c("lmobject1","lmobject2","lmobject3")
#or
names(regressionmodels.listed) = paste0("lmobject",1:length(regressionmodels.listed))
namesofmodels = names(regressionmodels.listed)
One other option is to use broom:
library(tibble)
library(broom)
library(tidyr)
library(dplyr)
library(purrr)
lm1 = lm(mpg ~ cyl,data=mtcars)
lm2 = lm(mpg ~ disp,data=mtcars)
lm3 = lm(mpg ~ hp,data=mtcars)
res = tibble(models=list(lm1,lm2,lm3))
res = res %>% mutate(names=paste0("model",1:n()),stats=map(models,glance))
# A tibble: 3 x 3
models names stats
<list> <chr> <list>
1 <lm> model1 <tibble [1 × 11]>
2 <lm> model2 <tibble [1 × 11]>
3 <lm> model3 <tibble [1 × 11]>
we can unnest this:
res %>% unnest(cols=stats)
# A tibble: 3 x 13
models names r.squared adj.r.squared sigma statistic p.value df logLik
<list> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <int> <dbl>
1 <lm> mode… 0.726 0.717 3.21 79.6 6.11e-10 2 -81.7
2 <lm> mode… 0.718 0.709 3.25 76.5 9.38e-10 2 -82.1
3 <lm> mode… 0.602 0.589 3.86 45.5 1.79e- 7 2 -87.6
# … with 4 more variables: AIC <dbl>, BIC <dbl>, deviance <dbl>,
# df.residual <int>
and display the columns you like:
res %>% unnest(cols=stats) %>% select(names,df,r.squared,adj.r.squared)
# A tibble: 3 x 4
names df r.squared adj.r.squared
<chr> <int> <dbl> <dbl>
1 model1 2 0.726 0.717
2 model2 2 0.718 0.709
3 model3 2 0.602 0.589
Upvotes: 2
Reputation: 1595
I came up with this fast solution. You want to store some summary statistics from a list of models (e.g. linear models from lm()
) in a data.frame
. I call this object result
which will be of dimensions NxP
where N
is the number of models you stored in your list and P
is the number of statistics you want to collect. In this case, P=3
for d.o.f., R-squared and Adjusted R-Squared.
Here I am using the built-in data mtcars
.
data("mtcars")
mod1 = lm( mpg ~ hp, data = mtcars )
mod2 = lm( mpg ~ wt, data = mtcars )
mod3 = lm( mpg ~ qsec, data = mtcars )
regressionmodels.listed = list( mod1, mod2, mod3 )
N = length( regressionmodels.listed )
results = data.frame( df = rep( NA_integer_, N ),
r.squared = rep( NA_real_, N ),
adj.r.squared = rep( NA_real_, N ) )
for ( i_mod in seq_along( regressionmodels.listed ) ) {
results[ i_mod, "df" ] = regressionmodels.listed[[ i_mod ]]$df
results[ i_mod, "r.squared" ] = summary(regressionmodels.listed[[ i_mod ]])$r.squared
results[ i_mod, "adj.r.squared" ] = summary(regressionmodels.listed[[ i_mod ]])$adj.r.squared
}
Could this be what you wanted?
If so, then substitute the mod*
with your models and you should be fine.
Upvotes: 1