# [R] take precisely one named argument

Gabor Grothendieck ggrothendieck at myway.com
Fri Dec 17 17:48:23 CET 2004

``` <Ted.Harding <at> nessie.mcc.ac.uk> writes:

:
: On 17-Dec-04 Ted Harding wrote:
: > I don't know the *best* way (expert R anatomists will know ... )
: > but the following dirty handed modification seems to do what
: > you want:
: >
: >   f <- function(z=NULL, a=NULL, b=NULL){
: >      if(!is.null(z)){
: >        stop("usage: f(a=...) or f(b=...)")
: >      }
: >      if(!xor(is.null(a), is.null(b))){
: >        stop("specify exactly one of a and b")
: >      }
: >      if(is.null(a)){return(2*b)}else{return(a)}
: >   }
: >
: > (This traps attempts to use f() with an un-named argument).
: >
: > Ted.
:
: Playing around with the above shows that not only does it
: give the correct response for correct usage, e.g. f(a=3) or f(b=3),
: but, serendipitously, it gives appropriate responses for just
: about any way you could think of using it wrongly:
:
: > f(3)
: Error in f(3) : usage: f(a=...) or f(b=...)
:
: > f(a=2,b=3)
: Error in f(a = 2, b = 3) : specify exactly one of a and b
:
: > f(d=3)
: Error in f(d = 3) : unused argument(s) (d ...)
:
: > f(a=2,d=3)
: Error in f(a = 2, d = 3) : unused argument(s) (d ...)
:

Here is a minor reduction of the above:

ff <- function(z, a = 0, b = 0) {
stopifnot(missing(z), xor(missing(a), missing(b)))
a+2*b
}

```