I want to do a recursive function call with modified arguments in R.
recursive_function_call <- function(call) {
fun_call <- as.list(call)
fun <- fun_call[[1]]
arguments <- fun_call[-1]
## Modify Arguments
arguments$drop_option <- NULL
## Call Function
result <- do.call(what = fun, args = arguments)
return(result)
}
recursive_function_call(match.call())
I want to call this function from an array of similar functions. If this gets called from a top-level function the variable fun
will be of type symbol
, while it gets on a lower level function call fun will be a function
.
My problem is that do.call()
fails when the function is a symbol, while for the arguments it's OK to be symbols.
My solution is to convert the symbol to a string.
if (is.symbol(fun_call[[1]])) fun <- as.character(fun_call[[1]]) else fun <- fun_call[[1]]
match. call returns a call in which all of the specified arguments are specified by their full names.
The first element of the list becomes the function part of the call, so should be a function or the name of one (as a symbol; a character string will not do). If you think of using as. call(<string>) , consider using str2lang(*) which is an efficient version of parse(text=*) . Note that call() and as.
As you’ve noticed, do.call
constructs and invokes a call expression (and invokes it) from a function name (or function) and a list of arguments. But you already have a call expression, no need for do.call
— so you can directly invoke it using eval
or eval.parent
:
recursive_function_call = function(call) {
call$drop_options = NULL
eval.parent(call)
}
recursive_function_call(match.call())
That said, I’m not sure what your function’s purpose is. Are you looking for Recall
?
Alternatively, you can use as.call
to coerce a list into a function call expression. And, once again, eval
then evaluates it:
eval.parent(as.call(fun_cal))
— in fact, as.call
is essentially the inverse of as.list
on a call expression: identical(as.call(as.list(call)), call)
is TRUE
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With