Как я могу получить доступ к имени объекта lm () в списке других объектов? - PullRequest
1 голос
/ 01 апреля 2020

У меня есть некоторые недисциплинированные данные, которые я пытался смоделировать с помощью ряда различных линейных моделей, которым я дал разные названия. Затем я создал фрейм данных под названием «сравниваемые совпадения». Я могу хранить некоторые из наиболее актуальных результатов из различных моделей, используя код ниже.

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
}

«Перечисленные модели регрессии» - это объект списка типов, который я создаю просто:

regressionmodels.listed <- list(fit1, fit2 ...etc)

То, что я не могу сделать любым итерационным способом, заключается в следующем:

for(i in 1:length(regressionmodels.listed))
{
namesofmodels[i] = deparse(substitute(regressionmodels.listed[[i]]))
}

Обратите внимание, что если я запускаю разбор кода на индивидуально подобранной модели, скажем, fit1, он работает. Я только не могу заставить его работать с элементами списка подогнанных моделей. Это, очевидно, «приятно иметь», но поскольку я буду сравнивать, может быть, 10 или более моделей, было бы действительно проще, если бы я мог найти способ сделать это и добавить его в другой мой фрейм данных выше. .

РЕДАКТИРОВАТЬ Вот как выглядит regressionmodels.listed:

regressionmodels.listed <- list(lmobject1, lmobject2, lmobject3)

Объекты lm создаются просто путем запуска линейной модели для различных комбинаций данных. ,

Ответы [ 2 ]

2 голосов
/ 01 апреля 2020

Ваш список моделей не назван, поэтому нет способа вернуть "lmobject1" и т. Д. c, один из способов - назвать их в начале:

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)

Еще один вариант - использовать метла:

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]>

мы можем удалить это:

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>

и отобразить нужные вам столбцы:

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
1 голос
/ 01 апреля 2020

Я придумал это быстрое решение. Вы хотите сохранить некоторую сводную статистику из списка моделей (например, линейные модели из lm()) в data.frame. Я называю этот объект result, который будет иметь размеры NxP, где N - это количество моделей, которые вы сохранили в своем списке, а P - это количество статистики, которую вы хотите собрать. В этом случае P=3 для степеней свободы, R-квадрата и Скорректированного R-квадрата.

Здесь я использую встроенные данные 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

}

Может ли это быть тем, что вы хотели? Если это так, то замените mod* вашими моделями, и все будет в порядке.

...