Home > OS >  Named arguments and ellipses together causing function errors?
Named arguments and ellipses together causing function errors?

Time:10-24

I have a wrapper function I am using to run a linear model. I am using but I am experiencing an unexpected error when I use the ellipses and the named arguments together.

Why is the lm_robust_wrapper3 having an error?

library(estimatr)
library(purrr)
f <- list(as.formula("wt ~ mpg"))
map(f, ~lm_robust(formula = .x, data = mtcars)) # works
#> [[1]]
#>              Estimate Std. Error   t value     Pr(>|t|)   CI Lower   CI Upper
#> (Intercept)  6.047255 0.39068137 15.478739 7.584436e-16  5.2493772  6.8451328
#> mpg         -0.140862 0.01802089 -7.816592 1.009640e-08 -0.1776655 -0.1040584
#>             DF
#> (Intercept) 30
#> mpg         30

lm_robust_wrapper1 <- function(...){
  map(f, ~lm_robust(formula = .x, data = mtcars))
}
lm_robust_wrapper1() # works
#> [[1]]
#>              Estimate Std. Error   t value     Pr(>|t|)   CI Lower   CI Upper
#> (Intercept)  6.047255 0.39068137 15.478739 7.584436e-16  5.2493772  6.8451328
#> mpg         -0.140862 0.01802089 -7.816592 1.009640e-08 -0.1776655 -0.1040584
#>             DF
#> (Intercept) 30
#> mpg         30





lm_robust_wrapper2 <- function(...){
  lm_robust(..., data = mtcars)
}  

lm_robust_wrapper2(formula = f[[1]]) # works
#>              Estimate Std. Error   t value     Pr(>|t|)   CI Lower   CI Upper
#> (Intercept)  6.047255 0.39068137 15.478739 7.584436e-16  5.2493772  6.8451328
#> mpg         -0.140862 0.01802089 -7.816592 1.009640e-08 -0.1776655 -0.1040584
#>             DF
#> (Intercept) 30
#> mpg         30




lm_robust_wrapper3 <- function(...){
  f <- list(as.formula("wt ~ mpg"))
  map(f, ~lm_robust(formula = .x, data = mtcars, ...))
}
lm_robust_wrapper3() # fails
#> Error in model.frame.default(terms(formula, lhs = lhs, rhs = rhs, data = data, : invalid type (language) for variable '(weights)'

Created on 2021-10-22 by the reprex package (v0.3.0)

CodePudding user response:

estimatr::lm_robust gets confused because NULL isn't an element of args(estimatr::lm_robust). You can use match.call(), match the args to eval it later in the map. Now the arguments related to estimatr::lm_robust are correctly identified, and the list of formulae f is going into the map.

Single formulae need to be put into a list, but you could change that with an if / else case handling.

lm_robust_wrapper3 <- function(...) {
  cl <- match.call()
  f <- cl[['f']][-1L]
  m <- match(formalArgs(estimatr::lm_robust), names(cl), 0L)
  m <- cl[c(1L, m)]
  m[[1L]] <- quote(estimatr::lm_robust)
  map(f, ~ {
    m[['formula']] <- .x
    eval(m, parent.frame()) 
  })
}

lm_robust_wrapper3(f=list(wt ~ mpg), data=mtcars)
# [[1]]
#              Estimate Std. Error   t value     Pr(>|t|)   CI Lower   CI Upper DF
# (Intercept)  6.047255 0.39068137 15.478739 7.584436e-16  5.2493772  6.8451328 30
# mpg         -0.140862 0.01802089 -7.816592 1.009640e-08 -0.1776655 -0.1040584 30

lm_robust_wrapper3(f=list(wt ~ mpg, qsec ~ mpg), data=mtcars, alpha=.001)
# [[1]]
#              Estimate Std. Error   t value     Pr(>|t|)   CI Lower   CI Upper DF
# (Intercept)  6.047255 0.39068137 15.478739 7.584436e-16  5.2493772  6.8451328 30
# mpg         -0.140862 0.01802089 -7.816592 1.009640e-08 -0.1776655 -0.1040584 30
# 
# [[2]]
#               Estimate Std. Error   t value     Pr(>|t|)    CI Lower   CI Upper DF
# (Intercept) 15.3547689 0.83511142 18.386491 6.998610e-18 13.64924386 17.0602940 30
# mpg          0.1241366 0.03941595  3.149399 3.688336e-03  0.04363845  0.2046347 30

When no f is provided in the arguments it doesn't terribly fail, just yields an empty list(), but you still may define a stop in the function.

lm_robust_wrapper3(f=NULL, data=mtcars)
# list()
  • Related