The MASS::stepAIC
function takes an lm
result as a parameter and does stepwise regression to find the "best" model. The following code is brain dead simple and works:
library(MASS)
data("mtcars")
lm1 = lm(mpg ~ ., mtcars)
step1 = stepAIC(lm1, direction = "both", trace = FALSE)
I'm trying to put this inside a function. Eventually I want to do more, but I can't even get these two lines of code to work when wrapped in a function:
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'
I'm running:
R version 3.6.2 (2019-12-12)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Linux Mint 19.1
Here is your culprit (within the fit_model
function). Notice the environment where the formula was created.
Browse[1]> str(formula)
Class 'formula' language mpg ~ .
..- attr(*, ".Environment")=<environment: R_GlobalEnv>
What you could do is perhaps force in a new environment
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
A solution based on do.call
and described at this link:
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)
As far as I can tell, this is a perfect case for using 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
Edit:
This is equivalent to:
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With