Here's a solution based on this section of Hadley Wickham's 'Advanced R' -- to_analyze() is modeled on the lm3() function from the subsection called 'Wrapping modelling functions', and to_predict_lsmeans() is modeled on the first example in the following section, called 'Evaluation environment':
set.seed(234)
sex <- sample(c("M", "F"), size=100, replace=TRUE)
age <- rnorm(n=100, mean=20 + 4*(sex=="F"), sd=0.1)
dsn <- data.frame(sex, age)
rm(sex, age) #remove sex and age from the global environment for reproducibility
library(tidyverse)
library(rlang)
#>
#> Attaching package: 'rlang'
#> The following objects are masked from 'package:purrr':
#>
#> %@%, as_function, flatten, flatten_chr, flatten_dbl,
#> flatten_int, flatten_lgl, flatten_raw, invoke, list_along,
#> modify, prepend, splice
to_analyze <- function(dep, indep, data, env = caller_env()){
dep <- enexpr(dep)
indep <- enexpr(indep)
data <- enexpr(data)
formula <- expr(!!dep ~ factor(!!indep))
glm_call <- expr(glm(!!formula, data = !!data))
expr_print(glm_call)
eval(glm_call, env)
}
to_predict_lsmeans <- function(dep, indep, data, env = caller_env()){
dep <- enexpr(dep)
dep_string <- as_string(dep)
indep <- enexpr(indep)
data <- enexpr(data)
formula <- expr(!!dep ~ factor(!!indep))
ta_call <- expr(to_analyze(!!dep, !!indep, !!data))
model <- eval(ta_call, env)
# need to store current environment so objects created within
# function can be accessed, too:
lsm_env <- env(env, model = model, dep_string = dep_string)
lsm_call <-
expr(
lsmeans::lsmeans(model, ~ factor(!!indep), offset= log((!!data)[[!!dep_string]]), type ="response" )
)
eval(lsm_call, lsm_env)
}
to_predict_lsmeans(dep=age, indep=sex, data=dsn)
#> glm(age ~ factor(sex), data = dsn)
#> sex lsmean SE df asymp.LCL asymp.UCL
#> F 26.98 0.01269 Inf 26.96 27.01
#> M 22.99 0.01348 Inf 22.97 23.02
#>
#> Confidence level used: 0.95
Created on 2020-02-29 by the reprex package (v0.3.0)