Re: [R] Passing (Optional) Arguments

From: Jason Q. McClintic <jqmcclintic_at_stthomas.edu>
Date: Tue, 25 Mar 2008 19:00:56 -0500

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Sir:

Thank you for your assistance. I am most interested in your suggestion

| You can use list(...) in foo3, and manually split the args to those
| that
| belong in foo1 and those that belong in foo2, and then construct calls
| from them.  (This allows you to recognize args that don't go to either
| place, and signal errors.)

as I am not especially interested in managing ever growing lists of arguments, especially in functions where there is a choice of methods each with its own distinct requisite arguments.

Is this an example of what you mean?

         foofun<-function(...){tf<-is.list(list(...));return(tf)}

which, for instance, can be invoked as:

        foofun(a=1,b=2,c=3)

and returns TRUE. This makes sense to me given arguments are supplied. Is the following in this context the correct way to handle "missing" arguments to a function--assuming someone is supposed to supply a, b, and c?

        foofun<-function(...){

	  argList<-list(...);
	  if(is.null(argList$a)==TRUE){argList$a<-1};
	  if(is.null(argList$b)==TRUE){argList$b<-2};
	  if(is.null(argList$c)==TRUE){argList$c<-3};

	  return(argList$a*argList$b*argList$c);

	}

Then would it be appropriate to use an "else if"-type construction to check for invalid argument types.

How would I know when there are extra args? If I use the second version of foofun and invoke it as

        foofun(a=1,b=2,c=3,d=4)

then I get 6 even though d is unused without an error message. How can I have it check? I think about trying to find the intersection of the set of desired argument names with the given set of argument names and if the intersection is not as desired, then return some sort of warning. Perhaps using ifelse?

Thanks again for your assistance.

Sincerely,

Jason Q. McClintic
- --
Jason Q McClintic
UST MB 1945
2115 Summit Avenue
St. Paul, MN 55105
jqmcclintic_at_stthomas.edu
mccl0219_at_tc.umn.edu

"It is insufficient to protect ourselves with laws, we must protect ourselves with mathematics."--Bruce Schneier

Duncan Murdoch wrote:

| Jason Q. McClintic wrote:

|> Dear List:
|>
|> In short, I am writing a number of functions as building blocks for
|> other functions and have some questions about scoping and passing
arguments.
|>
|> Suppose I have functions foo1, foo2, and foo3 such that:
|>
|> foo1<-function(a=1,b=TRUE,c=FALSE){#do stuff};
|> foo2<-function(x=1,y=FALSE,z=c(1,2,3,4)){#do stuff};
|> foo3<-function(lambda,...){lambda*foo1()*foo2()};
|>
|> I want to be able to pass a,b,c,x,y,z to the functions foo1 and foo2
|> though foo3 (whether I define default values or not). How do I do this?
|> I read a bit in the wiki about problems with partial argument matching
|> and argument matching (lesson: make argument names not match truncated
|> versions of other argument names in the "target" function).
|>
| That's tricky, because ... becomes one big list.  You have a few choices:
|
| foo1 and foo2 can gain a ... arg, and ignore it.  Then you pass ... to
| both of them.  Problem:  you can pass typos to them and won't get a
| complaint.
|
| foo3 can gain a,b,c,x,y,z args, and pass those along to foo1 and foo2.
| Problem:  duplication, maintenance problems, etc.
|
| You can use list(...) in foo3, and manually split the args to those that
| belong in foo1 and those that belong in foo2, and then construct calls
| from them.  (This allows you to recognize args that don't go to either
| place, and signal errors.)
|
| You can pass foo1Args and foo2Args as lists to foo3, and construct calls
| from those, e.g.
|
| foo3 <- function(lambda, foo1Args, foo2Args)
|   lambda*do.call(foo1, foo1Args)*do.call(foo2,foo2Args)
|
| There are other options (e.g. using local versions of foo1 and foo2
| within foo3) that  are variations on the ones above.
|
| It's hard to give good advice on this, because whatever you do will be a
| tradeoff.  You'll see variations on all of the above in the base packages.
|
| Duncan Murdoch

|> To get a better feel for things I've been playing with examples such as:
|>
|> b<-c(0.25,0.25);
|> fun<-function(a=1,...){a*b};
|>
|> fun() returns 0.25 0.25 as expected.
|> fun(a=2) returns 0.5 0.5 as expected.
|> However, fun(b=1) returns 0.25 0.25 when I want to overwrite b with the
|> value 1 and have it return 1.
|>
|> Likewise with
|>
|> fun<-function(a=1,...){a*return(b)};
|>
|> any argument I supply for b seems to be ignored.
|>
|> I understand as b is not defined within the function when I enter
|>
|> fun()
|>
|> lexical scoping means R looks for b up one level and, finding b, uses it.
|>
|> Thanks for any/all help.
|>
|> Sincerely,
|>
|> Jason Q. McClintic
|> --
|> Jason Q McClintic
|> UST MB 1945
|> 2115 Summit Avenue
|> St. Paul, MN 55105
|> jqmcclintic_at_stthomas.edu
|> mccl0219_at_tc.umn.edu
|>
|> "It is insufficient to protect ourselves with laws, we must protect
|> ourselves with mathematics."--Bruce Schneier
|>
|> ______________________________________________
|> R-help_at_r-project.org mailing list
|> https://stat.ethz.ch/mailman/listinfo/r-help
|> PLEASE do read the posting guide
http://www.R-project.org/posting-guide.html
|> and provide commented, minimal, self-contained, reproducible code.
|>

|
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iQEVAwUBR+mSNhMtGNvij6jtAQh8kwf+L0OnLMZ+4DKFpZ7YYalpIS+ybb3VrEak 9R7AwA7Rk4njUlYVj3cZlFz+shMAtNHbuJRCndTvKq+x9kzlqdpz/9ws28mfvlCB v8yqKaVBXtvLXTmg1c2GDRa649+T6IJa5YgAyJLJ5NiDKnW8bpx5HKz0k1w3VTsy 0T/FER/J30qXHVkLyXs7WAu7upn2qFE8SBed993g28tlHQzWlee1At1zjOw9QFHU 4CueYvRzRv474gBcchJg27iOHY4r1gCUtY3g7Fa4l3E77b2QJfT3eqlcTbKq4KzE EfuX5J1W/+HzRXrb0Hh2pbGm0pbXs4DgWLcJryuO50a6HJe+zubY+g== =F/P9
-----END PGP SIGNATURE-----



R-help_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. Received on Wed 26 Mar 2008 - 03:11:26 GMT

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Wed 26 Mar 2008 - 04:30:24 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-help. Please read the posting guide before posting to the list.

list of date sections of archive