Search code examples
rrlang

Create a call to `mice::with.mids()`


I am trying to create a call to mice::with.mids(), then evaluate it. It appears the call is being created, but then it cannot be evaluated (must be some environment/scoping issue?). I've created a pared down reproducible example below. Any assistance is greatly appreciated! Thank you!

mice_in_tbl_uvregression <- 
  function(data,   # mice data of class mids
           method, # regression method, eg. lm, glm
           formula = "hp ~ mpg", # character formula (needs to be character for other reasons)
           method.args = NULL # named list of other args that will be passed to `method=`
  ) {
    # construct the call
    fun_call <-
      rlang::call2(
        rlang::expr(with),
        data = data,
        expr = rlang::expr((!!method)(formula = !!as.formula(formula), !!!method.args))
      )
    
    # evaluate call
    eval(fun_call)
  }

set.seed(12345)
mice_in_tbl_uvregression(
  data = mice::mice(mtcars, m = 2),
  method = lm
)
#> Error in eval(predvars, data, env): object 'hp' not found

Created on 2021-06-27 by the reprex package (v2.0.0)


Solution

  • We could parse a string created (to extract the language call) before doing the evaluation

    mice_in_tbl_uvregression <- 
      function(data,   # mice data of class mids
               method, # regression method, eg. lm, glm
               formula = "hp ~ mpg", # character formula (needs to be character for other reasons)
               method.args = NULL # named list of other args that will be passed to `method=`
      ) {
        # construct the call
       
        fun_call <- parse(text = glue::glue("with(data = {deparse(substitute(data))}, expr = {deparse(substitute(method))}(as.formula({formula})))"))
        print(fun_call[[1]])
        out <- eval(fun_call)
        out$call$expr[[2]] <- out$call$expr[[2]][[2]]
       out
        
      }
    

    -testing

    set.seed(12345)
    out1 <- mice_in_tbl_uvregression(
      data = mice::mice(mtcars, m = 2),
      method = lm
    )
    

    -output

     out1
    call :
    with.mids(data = mice::mice(mtcars, m = 2), expr = lm(hp ~ mpg))
    
    call1 :
    mice::mice(data = mtcars, m = 2)
    
    nmis :
     mpg  cyl disp   hp drat   wt qsec   vs   am gear carb 
       0    0    0    0    0    0    0    0    0    0    0 
    
    analyses :
    [[1]]
    
    Call:
    lm(formula = as.formula(hp ~ mpg))
    
    Coefficients:
    (Intercept)          mpg  
         324.08        -8.83  
    
    
    [[2]]
    
    Call:
    lm(formula = as.formula(hp ~ mpg))
    
    Coefficients:
    (Intercept)          mpg  
         324.08        -8.83