Skip to content

advice on arguments

7 messages · Ben Bolker, Duncan Murdoch, Eric Lecoutre +2 more

#
I have a general style question about R coding.

   Suppose I'm writing a function (foo1) that calls other functions
(foo2, foo3, ...) which have complicated argument
lists (e.g. optim(), plot()), _and_
I may be calling several different functions in the body of
foo1.  Since foo2 and foo3 have different sets of arguments, I
can't just use "..." ; I did write some code a while ago that
would look at formals() to dissect out arguments that should
be passed to the different functions, but it seemed overly
complex.

  The particular case I have now is a little simpler.

  foo2 (points3d) and foo3 (spheres3d)
are both functions from the rgl package
that pass arguments such as color, alpha, etc. along to
an rgl.material() command with lots of possible arguments.
(The function may also call segments3d or lines3d, but
these all have the same arguments as points3d.)
However, to change the size of points you use "size"; to
change the size of spheres you use "radius".  Do I
(1) add "radius" to the argument list, cluttering up
the argument list for one particular special case?
(2) add "size" to the argument list, so that it doesn't
become part of "..." and I can say spheres3d(radius=size,...) ?
(3) do something like
    dotlist = list(...)
    if (type=="s" && !is.null(dotlist$size)) radius <- dotlist$size
and pull "size" out of ... myself (and make a note to that
effect in  the documentation)?
  (I guess another general solution to this is to ask for
lists of arguments, like MoreArgs in mapply(). Another
would be to go back and change spheres3d to make size
a synonym for radius ... )

  any thoughts?
    Ben Bolker
#
On 6/29/2006 12:53 PM, Ben Bolker wrote:
I would do (2) in general, but in this particular case it might not be 
right.  "size" is measured in pixels, and "radius" is measured in data 
units, so they really are different things.  You could try to fiddle it 
so the radius is set to the right number of units to match the number of 
pixels that were requested, but users can change the scale pretty easily.

Duncan Murdoch
#
On 6/30/2006 2:30 AM, Eric Lecoutre wrote:
There are some problems with this approach (as there are problems with 
all the other approaches; whether these matter is a matter of judgment):

  - It may require you to modify foo2 and foo3.  In this particular 
instance, foo2 and foo3 are in a package, not under Ben's direct control.

  - It breaks R's ability to warn you about typos.  For example,

foo1(sz =  3)

would not cause an unrecognized parameter error; both functions would 
accept and ignore the bad parameter setting.

  - It breaks the partial argument matching, e.g.

foo1(siz = 3)

would act just like the above, instead of like

foo1(size = 3)

Duncan Murdoch
#
Duncan Murdoch <murdoch at stats.uwo.ca> writes:
Is this viewed as a feature?  Having ( dataset=3 ) foul the namespace
for d, da, dat, data, etc... sounds miserable to me.


- Allen S. Rout
#
Here is an approach.  fn.dots takes a character string, fn.name, such as
a function name and a named list, dots.  If fn.name is "f", say, then
it returns all components of dots whose name is of the form f.somestring
removing the f. prefix as well as components containing unprefixed
strings. It would typically be used like this:

f.dots <- fn.dots("f", dots)
do.call("f", f.dots)

and the user can specify that x be passed to all functions by
naming it x, to just f by naming it f.x.  If both x and f.x appears
then f.x takes precedence in a call to f.

fn.dots <- function(fn.name, dots) {
	pat <- paste("^", fn.name, "[.]", sep = "")
	nm <- names(dots)
	fn.nm <- grep(pat, nm, value = TRUE)
	dots[sub(pat, "", fn.nm)] <- dots[fn.nm]
	dots[grep("^[^.]*[.]", nm, value = TRUE)] <- NULL
	dots
}


dots <- list(a = 33, f.a = 55, g.a = 44, b = 56, g.c = 99)
fn.dots("f", dots) # list(a = 55, b = 56)
fn.dots("g", dots) # list(a = 44, b = 56, c = 99)
fn.dots("h", dots) # list(a = 33, b = 56)
On 6/29/06, Ben Bolker <bolker at zoo.ufl.edu> wrote:
#
On 6/30/2006 10:49 AM, Allen S. Rout wrote:
I think there are mixed feelings about whether it is a feature or a 
misfeature, but it's a very old property of the S language.

Duncan Murdoch