Передача результата `lm` в` stepAIC` работает в скрипте, происходит сбой внутри функции - PullRequest
4 голосов
/ 29 апреля 2020

Функция MASS::stepAIC принимает результат lm в качестве параметра и выполняет пошаговую регрессию, чтобы найти «лучшую» модель. Следующий код прост в мозгу и работает:

library(MASS)
data("mtcars")

lm1 = lm(mpg ~ ., mtcars)
step1 = stepAIC(lm1, direction = "both", trace = FALSE)

Я пытаюсь поместить это в функцию. В конце концов я хочу сделать больше, но я даже не могу заставить эти две строки кода работать, когда они заключены в функцию:

fit_model = function(formula, data) {
  full_model = lm(formula = formula, data = data)
  step_model = stepAIC(full_model, direction = "both", trace = FALSE)
  return(step_model)
}

step2 = fit_model(mpg ~ ., mtcars)
Error in eval(predvars, data, env) : 
  invalid 'envir' argument of type 'closure' 

Я работаю:

R version 3.6.2 (2019-12-12)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Linux Mint 19.1

Ответы [ 3 ]

5 голосов
/ 29 апреля 2020

Вот ваш виновник (в функции fit_model). Обратите внимание на среду, в которой была создана формула.

Browse[1]> str(formula)
Class 'formula'  language mpg ~ .
  ..- attr(*, ".Environment")=<environment: R_GlobalEnv> 

Что вы можете сделать, это, возможно, форсировать в новой среде

fit_model = function(formula, data) {
  environment(formula) <- new.env()
  full_model = lm(formula = formula, data = data)
  step_model = stepAIC(full_model, direction = "both", trace = FALSE)
  return(step_model)
}

> step2

Call:
lm(formula = mpg ~ wt + qsec + am, data = data)

Coefficients:
(Intercept)           wt         qsec           am  
      9.618       -3.917        1.226        2.936 
2 голосов
/ 30 апреля 2020

Решение, основанное на do.call и описанное по этой ссылке :

fit_model = function(formula, data) {
  full_model <- do.call("lm", list(formula=formula, data=data))
  step_model <- stepAIC(full_model, direction = "both", trace = FALSE)
  return(step_model)
}
step2 <- fit_model(mpg ~ ., mtcars)
2 голосов
/ 29 апреля 2020

Насколько я могу судить, это идеальный случай для использования enquote:

fit_model <- function(formula, data) {
  formula <- enquote(formula)
  full_model <- lm(formula = formula, data = data)
  stepAIC(full_model, direction = "both", trace = FALSE)
}

fit_model(mpg ~ ., mtcars)
#
#Call:
#lm(formula = mpg ~ wt + qsec + am, data = data)
# 
#Coefficients:
#(Intercept)           wt         qsec           am  
#      9.618       -3.917        1.226        2.936  

Редактировать:

Это эквивалентно:

fit_model2 <- function(formula, data) {
  full_model <- lm(formula = formula, data = data)
  MASS::stepAIC(full_model, direction = "both", trace = FALSE)
}

fit_model2(quote(mpg ~ .), mtcars)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...