R: convert elements of list into expression from function input

663 Views Asked by At

I am writing a function, where the inputs are arguments and name of another function. I would like to convert these arguments and function name into an unevaluated expression or call. For example, if this is the call to the function:

huh_fun(
  data = mtcars
  method = lm,
  formula = hp ~ mpg,
  method.args = list(weights = drat, subset = rep(TRUE, 32)) # list of additional arguments
)

I would like the function to return the following expression/call, unevaluated:

lm(hp ~ mpg, data = mtcars, weights = drat, subset = rep(TRUE, 32))

I've had success quoting the data=, method=, and formula= arguments and combining them into a call. But cannot figure out how to quote the method.args= argument, and add the list elements into function arguments. Any and all pointers are appreciated. Thank you~

2

There are 2 best solutions below

0
On BEST ANSWER

Having fixed argument names in "huh_fun", we could construct an unevaluated call using "language" objects:

huh_fun = function(data, method, formula, method.args)
{
    ans = c(list(substitute(method), 
                 substitute(formula), 
                 data = substitute(data)), 
            as.list(substitute(method.args))[-1])
    as.call(ans)
}

huh_fun(
    data = mtcars,
    method = lm,
    formula = hp ~ mpg,
    method.args = list(weights = drat, subset = rep(TRUE, 32)))
#lm(hp ~ mpg, data = mtcars, weights = drat, subset = rep(TRUE, 
#    32))
0
On

You could use deparse(substitute(x)) and paste it together. Generate the call with str2lang.

huh_fun <- function(data, method, formula, method.args) {
  str2lang(paste0(deparse(substitute(method)), "(", deparse(substitute(formula)), ", ",
         "data = ", deparse(substitute(data)), ", ", 
         gsub("list\\((.*)\\)$", "\\1", deparse(substitute(method.args))),
         ")"))
}

Result

huh_fun(
  data=mtcars,
  method=lm,
  formula=hp ~ mpg,
  method.args=list(weights=drat, subset=rep(TRUE, 32)) # list of additional arguments
)

# lm(hp ~ mpg, data = mtcars, weights = drat, subset = rep(TRUE, 32))