[R] take precisely one named argument

2004-12-17 Thread Robin Hankin
Hi
I want a function that takes precisely one named argument and no
unnamed arguments. The named argument must be one of a or b.
If a is supplied, return a.  If b is supplied, return 2*b.
That is, the desired behaviour is:
R f(a=4)   #return 4
R f(b=33)  #return 66
R f(5)  #error
R f(a=3,b=5)   #error
R f(a=3,q=3)   #error
R f(q=3)   #error
The following function is intended to implement this:
f - function(a=NULL, b=NULL){
  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)}
}

It almost works, but  f(6) returns 6 (and should be an error).
What is the best way to accomplish my desired behaviour?
--
Robin Hankin
Uncertainty Analyst
Southampton Oceanography Centre
European Way, Southampton SO14 3ZH, UK
 tel  023-8059-7743
__
[EMAIL PROTECTED] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


RE: [R] take precisely one named argument

2004-12-17 Thread Liaw, Andy
 From: Liaw, Andy
 Here's my attempt:
 
  f - function(...) {
 + argList - list(...)
 + if (length(argList) != 1) stop(Wrong number of arguments!)
 + if (length(names(argList)) != 1 || ! names(argList) 
 %in% c(a, b))
 + stop(Wrong name for argument!)
 + x - argList[[1]] * if (names(argList) == a) 1 else 2
 + x
 + }
  f(a=6)
 Error in f(6) : Wrong name for argument!
  f(b=6)
 [1] 6
  f(c=6)
 [1] 12

This obviously _looks_ wrong, but that's only because I was running R under
ESS, and up-arrowed to edit the commands.  The correct transcript for this
part ought to look like:

 f(a=6)
[1] 6
 f(b=12)
[1] 24
 f(b=6)
[1] 12
 f(c=6)
Error in f(c = 6) : Wrong name for argument!

Andy

  f(c=6)
 Error in f(c = 6) : Wrong name for argument!
 
 HTH,
 Andy
 
 
  From: Robin Hankin
  
  Hi
  
  I want a function that takes precisely one named argument and no
  unnamed arguments. The named argument must be one of a or b.
  
  If a is supplied, return a.  If b is supplied, return 2*b.
  That is, the desired behaviour is:
  
  R f(a=4)   #return 4
  R f(b=33)  #return 66
  R f(5)  #error
  R f(a=3,b=5)   #error
  R f(a=3,q=3)   #error
  R f(q=3)   #error
  
  The following function is intended to implement this:
  
  f - function(a=NULL, b=NULL){
 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)}
  }
  
  
  It almost works, but  f(6) returns 6 (and should be an error).
  
  What is the best way to accomplish my desired behaviour?
  
  --
  Robin Hankin
  Uncertainty Analyst
  Southampton Oceanography Centre
  European Way, Southampton SO14 3ZH, UK
tel  023-8059-7743
  
  __
  [EMAIL PROTECTED] mailing list
  https://stat.ethz.ch/mailman/listinfo/r-help
  PLEASE do read the posting guide! 
  http://www.R-project.org/posting-guide.html
  
 
 
 __
 [EMAIL PROTECTED] mailing list
 https://stat.ethz.ch/mailman/listinfo/r-help
 PLEASE do read the posting guide! 
 http://www.R-project.org/posting-guide.html
 
 
 --
 
 Notice:  This e-mail message, together with any attachments, 
 contains information of Merck  Co., Inc. (One Merck Drive, 
 Whitehouse Station, New Jersey, USA 08889), and/or its 
 affiliates (which may be known outside the United States as 
 Merck Frosst, Merck Sharp  Dohme or MSD and in Japan, as 
 Banyu) that may be confidential, proprietary copyrighted 
 and/or legally privileged. It is intended solely for the use 
 of the individual or entity named on this message.  If you 
 are not the intended recipient, and have received this 
 message in error, please notify us immediately by reply 
 e-mail and then delete it from your system.
 --
 


__
[EMAIL PROTECTED] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


RE: [R] take precisely one named argument

2004-12-17 Thread Ted Harding
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 ...)

etc.

Ted.



E-Mail: (Ted Harding) [EMAIL PROTECTED]
Fax-to-email: +44 (0)870 094 0861  [NB: New number!]
Date: 17-Dec-04   Time: 13:47:34
-- XFMail --

__
[EMAIL PROTECTED] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


Re: [R] take precisely one named argument

2004-12-17 Thread Peter Dalgaard
BXC (Bendix Carstensen) [EMAIL PROTECTED] writes:

 specify:
 
 f - function(...,a=NULL,b=NULL) {...etc

Or (variant of same)

f - function(..., a, b) {
if (nargs() != 1 || length(list(...)))
  stop(precisely one of a=x or b=y must be given)
else
  if (missing(a)) 2*b else a
}


-- 
   O__   Peter Dalgaard Blegdamsvej 3  
  c/ /'_ --- Dept. of Biostatistics 2200 Cph. N   
 (*) \(*) -- University of Copenhagen   Denmark  Ph: (+45) 35327918
~~ - ([EMAIL PROTECTED]) FAX: (+45) 35327907

__
[EMAIL PROTECTED] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html


Re: [R] take precisely one named argument

2004-12-17 Thread Gabor Grothendieck
 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
}

__
[EMAIL PROTECTED] mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html