Custom wrapper function returning error: object not found

Hi there,

I've written a wrapper function for modeling and keep running into issues where objects inside the function are not found, despite the same code running just fine outside of the function.

From what I've read it appears to be related to scope or perhaps non-standard evaluation. I've tried working through the info here and here, but I have not been able to 1) make this work, and 2) fully understand the problem.

Below is a reproducible example (very simplified):

library(tidyverse)
#> Warning: package 'tidyverse' was built under R version 3.6.3
#> Warning: package 'ggplot2' was built under R version 3.6.3
#> Warning: package 'tidyr' was built under R version 3.6.3
library(nlme)
#> 
#> Attaching package: 'nlme'
#> The following object is masked from 'package:dplyr':
#> 
#>     collapse
library(janitor)
#> 
#> Attaching package: 'janitor'
#> The following objects are masked from 'package:stats':
#> 
#>     chisq.test, fisher.test
library(r2glmm)
#> Warning: package 'r2glmm' was built under R version 3.6.3


example_data <- clean_names(MathAchieve)


# A wrapper function that works -------------------------------------------

# Partial R-squared
model_1 <- lme(math_ach ~ ses + sex,
               random = ~ 1|school,
               method = "ML", data = example_data)

r2 = r2beta(model = model_1, partial = TRUE, method = 'sgv') %>%
  data.frame() %>%
  select(Effect, Rsq)

r2
#>      Effect        Rsq
#> 1     Model 0.10606854
#> 2       ses 0.09328673
#> 3 sexFemale 0.01060333


# A wrapper function that does NOT work -----------------------------------

test_function <- function(test_formula, test_data){
  
  temp_model <- lme(test_formula,
                    random = ~ 1|school,
                    method = "ML", data = test_data)

  r2 = r2beta(model = temp_model, partial = TRUE, method = 'sgv')
  
    # Keep the effects' r-squareds for later
  return(select(data.frame(r2), Effect, Rsq))
}

ex_formula <- as.formula(math_ach ~ ses + sex)

test_function(test_formula = ex_formula, test_data = example_data)
#> Error in eval(x$call$fixed): object 'test_formula' not found

Created on 2020-07-09 by the reprex package (v0.3.0)

I'm hoping someone could show me how to rewrite the wrapper function so it works, and if possible explain what it is that's causing the issue so that I can generalize this to something more complex if needed. Thanks!

This simple example works:

train_lm <- function(form_obj, data_obj){
  my_model <- lm(form_obj, data = data_obj) 
  return(my_model)
}

my_formula <- as.formula(mpg ~ .)

lm_model <- train_lm(my_formula, mtcars)

summary(lm_model)

Thanks @phil_hummel. The issue at hand requires using lme() though and being able to extract the partial r-squared within the function.

A colleague provided the solution below, which I have been able to run successfully:

library(tidyverse)
library(nlme)
#> 
#> Attaching package: 'nlme'
#> The following object is masked from 'package:dplyr':
#> 
#>     collapse
library(janitor)
#> 
#> Attaching package: 'janitor'
#> The following objects are masked from 'package:stats':
#> 
#>     chisq.test, fisher.test
library(r2glmm)


example_data <- clean_names(MathAchieve)


test_function2 <- function(formula, data) {
  
  temp_model <- lme(formula, random = ~ 1 | school, method = "ML", data = data)
  
  temp_model$call$fixed <- formula
  
  r2 <- r2beta(model = temp_model, partial = TRUE, method = 'sgv')
  
  return(dplyr::select(data.frame(r2), Effect, Rsq))
  
}

ex_formula <- as.formula(math_ach ~ ses + sex)

test_function2(formula = ex_formula, data = example_data)
#>      Effect        Rsq
#> 1     Model 0.10606854
#> 2       ses 0.09328673
#> 3 sexFemale 0.01060333

Created on 2020-07-28 by the reprex package (v0.3.0)