Создать al oop для выбора модели в R - PullRequest
1 голос
/ 10 февраля 2020

Я пытаюсь легко протестировать целый ряд различных моделей и сравнить значения AI C / R-sq, чтобы выбрать правильную. У меня возникли проблемы с сохранением данных между списками и фреймами данных.

фрейм данных. Я собираюсь смоделировать:

set.seed(1)
df <- data.frame(response=runif(50,min=50,max=100),
                 var1 = sample(1:20,50,replace=T),
                 var2 = sample(40:60,50,replace = T))

список тестируемых формул:

formulas  <- list( response ~ NULL,
                   response ~ var1,
                   response ~ var2,
                   response ~ var1 + var2,
                   response ~ var1 * var2)

Итак, я хочу создать al oop это смоделирует все эти формулы, извлечет значения Formula, AI C и R-sq в таблицу, и позвольте мне отсортировать их, чтобы найти лучшую. У меня проблема в том, что я не могу извлечь имя формулы как "Response ~ var1", вместо этого оно продолжает появляться как "Response" "~" "var1", если я пытаюсь извлечь как символьный объект. Или, если я извлеку список (как показано ниже), то получится так:

[[1]]
response ~ NULL

[[2]]
[1] 415.89

[[3]]
[1] 0

И я не могу легко вставить эти элементы списка во фрейм данных. Вот что я попробовал:

selection <- matrix(ncol=3)
colnames(selection) <- c("formula","AIC","R2") # create a df to store results in
for ( i in 1:length(formulas)){
  mod <- lm( formula = formulas[[i]], data= df)
  mod_vals <- c(extract(formulas[[i]]), 
                round(AIC(mod),2), 
                round(summary(mod)$adj.r.squared,2)
  )
  selection[i,] <- mod_vals[]
}

Есть идеи? Мне также не нужно хранить его как для l oop, я просто хочу проверить вместе длинный список моделей.

Спасибо.

1 Ответ

3 голосов
/ 10 февраля 2020

Вы можете использовать от lapply до l oop для каждой формулы и извлекать соответствующую статистику c из модели и связывать наборы данных вместе.

do.call(rbind, lapply(formulas, function(x) {
   mod <- lm(x, data= df)
   data.frame(formula = format(x), 
              AIC = round(AIC(mod),2), 
              r_square = round(summary(mod)$adj.r.squared,2))
}))

#                formula    AIC r_square
#1        response ~ NULL 405.98     0.00
#2        response ~ var1 407.54    -0.01
#3        response ~ var2 407.90    -0.02
#4 response ~ var1 + var2 409.50    -0.03
#5 response ~ var1 * var2 410.36    -0.03

Или с purrr

purrr::map_df(formulas, ~{
  mod <- lm(.x, data= df)
 data.frame(formula = format(.x), 
            AIC = round(AIC(mod),2), 
            r_square = round(summary(mod)$adj.r.squared,2))
})
...