Reputation: 661
I use the function caRamel from the package with the same name. The function takes another function my_func as an argument....
caRamel(
fn=my_func,
other_caRamel_parameters...
)
my_func is a function taking a unique parameter i (by design, mandatory and given by the caRamel function):
my_func <- function(i) {
require(somelib)
my_path = "C:/myfolder/"
do things with i
...
}
By design, there is no way to pass further arguments to the my_func function inside the caRamel function and I have to hard code everything like the my_path variable for example inside my_func.
However, I would like to be able to pass my_path and others variables as parameters in the caRamel function like so:
caRamel(
fn=my_func,
other_caRamel_parameters...,
my_path="C:/myfolder/", ...
)
with:
my_func <- function(i, my_path) {
require(somelib)
my_path = my_path
do things with i
...
}
I was then wondering if it was possible to write a "wrapper" in this case so that further parameters can be passed to my_func? What could be the options to achieve that?
Upvotes: 1
Views: 265
Reputation: 18551
We can use {purrr} and {rlang} in a custom myCaRamel
function which only takes the ellipsis ...
as argument.
First we capture the dots with rlang::list2(...)
.
Then we get all formals of the caRamel
function as names with rlang::fn_fmls_names
.
Now we differentiate between arguments which go into the caRamel
function and those which go into your custom function.
We use purrr::partial
to supply the argument which go into your my_fun
.
Then we call the original caRamel
function using the partial function we created together with the arguments that go in to caRamel
.
In the example below I rlang::expr
in the last call to show that it is working. Please delete the expr()
around the last call to make it actually work.
The downside is that every argument needs to be correctly named. Unnamed arguments and partial matching won't work. Further, if my_fun
and caRamel
contain arguments with similar names they only go into caRamel
and won't reach my_fun
.
library(purrr)
library(rlang)
library(caRamel)
my_fun <- function(x, my_path) {
# use my_path
# and some x
}
myCaRamel <- function(...) {
dots <- rlang::list2(...)
caramel_args <- rlang::fn_fmls_names(caRamel)
caramel_args_wo_fun <- caramel_args["func" != caramel_args]
other_args <- names(dots)[!names(dots) %in% caramel_args]
my_fn <- dots[["func"]]
my_fn <- purrr::partial(my_fn, !!! dots[other_args])
rlang::expr( # just to show correct out put - delete this line
caRamel(func = my_fn,
!!! dots[names(dots) %in% caramel_args_wo_fun])
) # delete this line
}
myCaRamel(func = my_fun,
my_path = "C:/myfolder/",
nvar = 10)
#> caRamel(func = my_fn, nvar = 10)
Created on 2021-12-11 by the reprex package (v2.0.1)
Upvotes: 1