I am trying to write a function that calls another function that requires formula arguments. However, I'm not able to pass the y ~ x arguments to the inner function.
Without the wrapping function it works:
test.df <- data.frame("test.x" = c(1,1,1,2,2), "test.y" = 1:5)
my.result <-lm(data = test.df, formula = test.y ~ test.x)
But I want this to work:
example.function <- function(my.data, my.y){
my.result <- lm(data = my.data, formula = my.y ~ test.x)
return(my.result)
}
example.function(my.data = test.df, my.y = test.y)
# Error in eval(predvars, data, env) : object 'test.y' not found
example.function(my.data = test.df, my.y = "test.y")
# Error in model.frame.default(formula = my.y ~ test.x, data = my.data, :
# variable lengths differ (found for 'test.x')
I tried to use {{}}
but this also doesn't work:
example.function <- function(my.data, my.y){
my.result <- lm(data = my.data, formula = {{my.y}} ~ test.x)
return(my.result)
}
example.function(my.data = test.df, my.y = test.y)
# Error in eval(predvars, data, env) : object 'test.y' not found
example.function(my.data = test.df, my.y = "test.y")
# Error in model.frame.default(formula = { :
# variable lengths differ (found for 'test.x')
And I also tried to use enquo()
and !!
but this doesn't work either:
example.function <- function(my.data, my.y){
enquo(my.y)
my.result <- lm(data = my.data, formula = !! my.y ~ test.x)
return(my.result)
}
example.function(my.data = test.df, my.y = test.y)
# Error in eval(predvars, data, env) : object 'test.y' not found
example.function(my.data = test.df, my.y = "test.y")
# Error in !my.y : invalid argument type
Thank you for any help understanding this!
This gives what was asked for.
On the other hand you might consider not using non-standard evaluation (NSE) and instead pass a character string for my.y
since then it becomes easy to pass a variable holding the variable name and not just hard coding the call. Also the code becomes shorter. We show that as example.function2
at the end.
example.function <- function(my.data, my.y) {
my.y <- deparse(substitute(my.y))
fo <- reformulate("test.x", my.y)
do.call("lm", list(fo, substitute (my.data)))
}
example.function(my.data = test.df, my.y = test.y)
giving
Call:
lm(formula = test.y ~ test.x, data = test.df)
Coefficients:
(Intercept) test.x
-0.5 2.5
Same but without NSE. Output is the same.
example.function2 <- function(my.data, my.y) {
fo <- reformulate("test.x", my.y)
do.call("lm", list(fo, substitute (my.data)))
}
example.function2(my.data = test.df, my.y = "test.y")