Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to pass the "..." parameters in the parent function to its two children functions in r

Tags:

function

r

I am trying to pass a set of parameters into a function. This function has two sub functions that take part of the above set of parameters.

In the following "SIMPLIFIED" example f_combined is a function that takes ... I would like to make the following function call such that xx is passed to f_sqr and yy is passed to f_plus:

f_combined(xx = 2, yy = 2)

but it would give me an error:

Error in f_sqr(...) : unused argument (yy = 2) 

any suggustions?

f_sqr <- function(xx =1){
  xx ^ 2
}

f_plus <- function(yy =1){
  yy + 1
}

f_combined <- function(...){
  f_sqr(...) + f_plus(...)
}
like image 592
kindadolf Avatar asked Sep 09 '14 16:09

kindadolf


People also ask

How do you pass a function as a parameter in R?

Adding Arguments in R We can pass an argument to a function while calling the function by simply giving the value as an argument inside the parenthesis.

How parameters are passed to a function?

Parameter passing involves passing input parameters into a module (a function in C and a function and procedure in Pascal) and receiving output parameters back from the module. For example a quadratic equation module requires three parameters to be passed to it, these would be a, b and c.

How many parameters can be passed to a method?

Information can be passed to methods as parameter. Parameters act as variables inside the method. Parameters are specified after the method name, inside the parentheses. You can add as many parameters as you want, just separate them with a comma.


2 Answers

You can either access ... as a named pairwise list or access it by order ..n

f_sqr <- function(xx =1){xx ^ 2}
f_plus <- function(yy =1){yy + 1}

f_combined <- function(...){
  print(f_sqr(list(...)$xx))
  print(f_plus(list(...)$yy))
  print(f_sqr(..1))
  print(f_plus(..2))
}
f_combined( yy = 1, xx = 10)

[1] 100 (element with name xx of the list ...)
[1] 2 (element with name yy of the list ...)
[1] 1 (the first argument in the list ...)
[1] 11 (the second argument in the list ...)

Output of ?"..."

10.4 The ‘...’ argument

Another frequent requirement is to allow one function to pass on argument settings to another. For example many graphics functions use the function par() and functions like plot() allow the user to pass on graphical parameters to par() to control the graphical output. (See The par() function, for more details on the par() function.) This can be done by including an extra argument, literally ‘...’, of the function, which may then be passed on. An outline example is given below.

 fun1 <- function(data, data.frame, graph=TRUE, limit=20, ...) {
   [omitted statements]
   if (graph)
     par(pch="*", ...)
   [more omissions]
 } 

Less frequently, a function will need to refer to components of ‘...’. The expression list(...) evaluates all such arguments and returns them in a named list, while ..1, ..2, etc. evaluate them one at a time, with ‘..n’ returning the n'th unmatched argument.

like image 131
B.Mr.W. Avatar answered Oct 28 '22 21:10

B.Mr.W.


Alternatively you would query a function's formals() to see what named parameters it is expecting and pass along only those. If the "child" function accepts ..., then we will pass along all arguments. This method would not work well for positional arguments.

f_combined <- function(..., .fns =list(f_sqr, f_plus), .reduce=`+`){
   dots <- list(...)
   Reduce(.reduce, lapply(.fns, function(f) {
       if ("..." %in% names(formals(f))) {
           do.call(f, dots)
       } else if ( any( names(dots) %in% names(formals(f)) ) ) {
           do.call(f, dots[names(formals(f))])
       } else {
           f()
       }
   }))
}

Here i've set the two functions to run as a parameter (.fns=list(f_sqr, f_plus)) so they can be easily changed or more can be effortlessly added. I've also set a parameter specifying how to combine those values should you want to do something other than sum them (.reduce='+'). But the basic idea is find the best set of mathching named parameters and pass them along. Since your "child" function have default values for their parameters as well, they will run when you pass along no parameters as well.

Here are some example calls

f_combined()
# [1] 3
f_combined(xx=2)
# [1] 6
f_combined(yy=2)
# [1] 4
f_combined(xx = 2, yy = 2)
# [1] 7
like image 23
MrFlick Avatar answered Oct 28 '22 21:10

MrFlick