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()