[Rd] Expanding partial names
Charles Dupont
charles.dupont at vanderbilt.edu
Thu Mar 9 17:19:53 CET 2006
Duncan Murdoch wrote:
> Okay, here's my effort based on Deepayan's and Charles' ideas. The
> newArgs function is not what I'd call transparent, but I like the way
> the wrapper looks.
>
> > newArgs <- function(..., Params) {
> + f <- function(...) list(...)
> + formals(f) <- c(Params, formals(f))
>
> + b <- as.list(body(f))
> + body(f) <- as.call(c(b[1], names, b[-1]))
> + f(...)
> + }
> >
> > lowlevel <- function(longname = 1) {
> + cat("longname = ", longname, "\n")
> + }
> >
> > newDefaults <- list(longname=2)
> >
> > wrapper <- function (...)
> + do.call("lowlevel", newArgs(..., Params=newDefaults))
>
> newArgs sets up f to look like
>
> function (longname = 2, ...) list(longname = longname, ...)
>
> and then calls it. The thing I like about this, as opposed to using
> pmatch, is that I'm sure the partial matching is what's used by R's
> argument matching, whereas that's only pretty likely with pmatch.
>
> I also sort of like these lines:
>
> + names <- as.list(names(Params))
> + names(names) <- names
> + names <- lapply(names, as.name)
>
> but maybe I should have named Params as names, so they looked like this:
>
> + names <- as.list(names(names))
> + names(names) <- names
> + names <- lapply(names, as.name)
>
> And of course I like the fact that this seems to work, but we've seen
> several versions that do that:
>
> > wrapper()
> longname = 2
> > wrapper(longname=3)
> longname = 3
> > wrapper(long=3)
> longname = 3
> > wrapper(long=20)
> longname = 20
> > wrapper(junk=20)
> Error in lowlevel(longname = 2, junk = 20) :
> unused argument(s) (junk ...)
>
If while running the program you don't need to change either the default
options of the wrapper or the change which lowlevel function is called
this approach works well if you calculations are not too complicated.
createWrapper <- function(FUN, Params) {
as.function(c(replace(formals(FUN), names(Params), Params),
body(FUN)))
}
const <- 10
newDefaults <- alist(cat = 2,
longname = if(cat == 2){
if(!missing(dog)) cat + dog
else cat + 2
} else cat * const, dog=)
wrapper <- createWrapper(lowlevel, newDefaults)
> wrapper()
longname = 4
> wrapper(longname=3)
longname = 3
> wrapper(long=3)
longname = 3
> wrapper(3)
longname = 3
> wrapper(cat=4)
longname = 40
> wrapper(dog=6)
longname = 8
> wrapper(cat=4, dog=6)
longname = 40
> wrapper(long=3, cat=4, dog=6)
longname = 3
Charles
More information about the R-devel
mailing list