How to write a wrapper function that can take default values ​​when the objective function has one?

I would like to write a more or less general calling targetf object that will keep its default settings.

Suppose we have provided some third-party targetf library:

 targetf<-function(x=1,...){ print(paste("x =",x)) } 

How to write wrapperf that respects the default arguments of targetf , so calling wrapperf() will not give the error message Error in paste("x =", x) : argument "x" is missing, with no default ?

The obvious candidate wrapperf1<-function(x,y) {targetf(x=x)} does not work and does not work with wrapperf1() .

wrapperf2<-function(...) {targetf(...)} behaves correctly, but for me it does not work, because I only need to pass the argument x (and, possibly, reserve ... for other functions in the body wrapperf ).

Perhaps to solve the problem I will have to play with ellipsis filtering, which is now terra incognita for me ...


One idea on how to solve the problem: maybe I will need to create a specially created object ... from scratch in wrapperf to make pseudo-code like this:

 wrapperfX<-function(x,y,...) { ...<-if(missing(x){ list() }else{ list(x=x) } targetf(...) } 

But I have no idea how to even begin to carry out tasks in the ellipsis ... maybe at all? I posed this question separately on SO: Is it possible to create an object with an ellipsis ( … ) .


Since the problem has not yet been resolved, I decided to post this question to r-help@r-project.org

+4
source share
1 answer

I will answer an even more complicated setup (I replaced targetf with lib* names). The bar functions are nested inside foo , so their default values ​​are not easily visible to the user.

 libfoo<-function(par1=1,...) { if (missing(par1)) { warning("par1 is missing!!") } print(paste0('par1: ',par1)) libbar(...) } libbar<-function(par2=1) { if (missing(par2)) { warning("par2 is missing!!") } print(paste0('par2: ',par2)) } libfoo2<-function(par3=1,...) { if (missing(par3)) { warning("par3 is missing!!") } print(paste0('par3: ',par3)) libbar2(...) } libbar2<-function(par4=1) { if (missing(par4)) { warning("par4 is missing!!") } print(paste0('par4: ',par4)) } 

Wrapper:

 wrapfun<-function(x,par1=3,...,par3,par4) { libfoo(par1,...) #With dots everything is simple pars<-list() if(!missing(par3)) { pars<-c(pars,par3=par3) } if(!missing(par4)) { pars<-c(pars,par4=par4) } do.call(libfoo2,pars) #This is how we can pass specific arguments, and respecting missings properly. } 

This is some conclusion:

 wrapfun(par1=5,par2=5,par3=5,par4=5) # [1] "par1: 5" # [1] "par2: 5" # [1] "par3: 5" # [1] "par4: 5" wrapfun() # [1] "par1: 3" # [1] "par2: 1" # [1] "par3: 1" # [1] "par4: 1" # Warning messages: # 1: In libbar(...) : par2 is missing!! # 2: In (function (par3 = 1, ...) : par3 is missing!! # 3: In libbar2(...) : par4 is missing!! wrapfun(par4=5) # [1] "par1: 3" # [1] "par2: 1" # [1] "par3: 1" # [1] "par4: 5" # Warning messages: # 1: In libbar(...) : par2 is missing!! # 2: In (function (par3 = 1, ...) : par3 is missing!! 
+1
source

Source: https://habr.com/ru/post/1501054/


All Articles