Function which runs lm over different variables
You can fix this problem by using the quo_name
's and formula
:
lmfun <- function(data, y, x) {
y <- enquo(y)
x <- enquo(x)
model_formula <- formula(paste0(quo_name(y), "~", quo_name(x)))
lm(model_formula, data = data)
}
lmfun(mtcars, mpg, disp)
# Call:
# lm(formula = model_formula, data = data)
#
# Coefficients:
# (Intercept) disp
# 29.59985 -0.04122
If the arguments are unquoted, then convert to symbol (sym
) after changing the quosure to string (quo_name
) and evaluate the expression in lm
(similar to the OP's syntax of lm
)
library(rlang)
lmfun <- function(data, y, x) {
y <- sym(quo_name(enquo(y)))
x <- sym(quo_name(enquo(x)))
expr1 <- expr(!! y ~ !! x)
model <- lm(expr1, data = data)
model$call$formula <- expr1 # change the call formula
model
}
lmfun(mtcars, mpg, disp)
#Call:
#lm(formula = mpg ~ disp, data = data)
#Coefficients:
#(Intercept) disp
# 29.59985 -0.04122
An option if we are passing strings would be convert to symbols with ensym
and then quote
it in lm
lmfun <- function(data, y, x) {
y <- ensym(y)
x <- ensym(x)
expr1 <- expr(!! y ~ !! x)
model <- lm(expr1, data = data)
model$call$formula <- expr1 # change the call formula
model
}
lmfun(mtcars, 'mpg', 'disp')
#Call:
#lm(formula = mpg ~ disp, data = data)
#Coefficients:
#(Intercept) disp
# 29.59985 -0.04122
NOTE: Both the options are from tidyverse
Another solution:
lmf2 <- function(data,y,x){
fml <- substitute(y~x, list(y=substitute(y), x=substitute(x)))
lm(eval(fml), data)
}
lmf2(mtcars, mpg, disp)
# Call:
# lm(formula = eval(fml), data = data)
#
# Coefficients:
# (Intercept) disp
# 29.59985 -0.04122
Or, equivalently:
lmf3 <- function(data,y,x){
lm(eval(call("~", substitute(y), substitute(x))), data)
}