I'm writing wrappers for some functions that change some of the default arguments. I'd rather not list all of the arguments for the low level functions because there are about a dozen wrapper functions, and about 20 arguments to lowlevel. Instead I'm trying something like this: lowlevel <- function(longname = 1) { cat("longname = ", longname, "\n") } wrapper <- function(...) { newargs <- list(longname = 2) newargs[names(list(...))] <- list(...) do.call("lowlevel", newargs) } This almost works: > wrapper() longname = 2 > wrapper(longname = 3) longname = 3 But it fails if I try to use partial argument matching: > wrapper(long=4) Error in lowlevel(longname = 2, long = 4) : unused argument(s) (long ...) because long isn't matched to longname. Is there a reasonable way to do this (e.g. using pmatch or charmatch) other than listing all the low level arguments in the argument list to wrapper? Duncan Murdoch
Try this: wrapper <- function(...) { args <- list(...) if (length(args)) { nf <- names(formals(lowlevel)) nams <- nf[pmatch(names(args), nf)] args <- replace(list(longname = 2), nams, args) } do.call("lowlevel", args) } Here is a test:> wrapper()longname = 1> wrapper(longname = 34)longname = 34> wrapper(long = 34)longname = 34 On 3/7/06, Duncan Murdoch <murdoch at stats.uwo.ca> wrote:> I'm writing wrappers for some functions that change some of the default > arguments. I'd rather not list all of the arguments for the low level > functions because there are about a dozen wrapper functions, and about > 20 arguments to lowlevel. Instead I'm trying something like this: > > lowlevel <- function(longname = 1) { > cat("longname = ", longname, "\n") > } > > wrapper <- function(...) { > newargs <- list(longname = 2) > newargs[names(list(...))] <- list(...) > do.call("lowlevel", newargs) > } > > This almost works: > > > wrapper() > longname = 2 > > wrapper(longname = 3) > longname = 3 > > But it fails if I try to use partial argument matching: > > > wrapper(long=4) > Error in lowlevel(longname = 2, long = 4) : > unused argument(s) (long ...) > > because long isn't matched to longname. Is there a reasonable way to do > this (e.g. using pmatch or charmatch) other than listing all the low > level arguments in the argument list to wrapper? > > Duncan Murdoch > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >
Duncan Murdoch wrote:> I'm writing wrappers for some functions that change some of the default > arguments. I'd rather not list all of the arguments for the low level > functions because there are about a dozen wrapper functions, and about > 20 arguments to lowlevel. Instead I'm trying something like this: > > lowlevel <- function(longname = 1) { > cat("longname = ", longname, "\n") > } > > wrapper <- function(...) { > newargs <- list(longname = 2) > newargs[names(list(...))] <- list(...) > do.call("lowlevel", newargs) > } > > This almost works: > > > wrapper() > longname = 2 > > wrapper(longname = 3) > longname = 3 > > But it fails if I try to use partial argument matching: > > > wrapper(long=4) > Error in lowlevel(longname = 2, long = 4) : > unused argument(s) (long ...) > > because long isn't matched to longname. Is there a reasonable way to do > this (e.g. using pmatch or charmatch) other than listing all the low > level arguments in the argument list to wrapper? > > Duncan MurdochIf all you are doing is changing the default values of some arguments this should work. wrapper <- lowlevel formals(wrapper) <- replace(formals(lowlevel), c("longname"), list(2)) Charles
On 3/7/06, Duncan Murdoch <murdoch at stats.uwo.ca> wrote:> I'm writing wrappers for some functions that change some of the default > arguments. I'd rather not list all of the arguments for the low level > functions because there are about a dozen wrapper functions, and about > 20 arguments to lowlevel. Instead I'm trying something like this: > > lowlevel <- function(longname = 1) { > cat("longname = ", longname, "\n") > } > > wrapper <- function(...) { > newargs <- list(longname = 2) > newargs[names(list(...))] <- list(...) > do.call("lowlevel", newargs) > } > > This almost works: > > > wrapper() > longname = 2 > > wrapper(longname = 3) > longname = 3 > > But it fails if I try to use partial argument matching: > > > wrapper(long=4) > Error in lowlevel(longname = 2, long = 4) : > unused argument(s) (long ...) > > because long isn't matched to longname. Is there a reasonable way to do > this (e.g. using pmatch or charmatch) other than listing all the low > level arguments in the argument list to wrapper?One trick I often use that is different from any of the suggestions I have seen so far (and is more transparent IMO) is the following: lowlevel <- function(longname = 1) { cat("longname = ", longname, "\n") } wrapper <- function(...) { newArgs <- function(longname = 2, ...) list(longname = longname, ...) do.call("lowlevel", newArgs(...)) } which gives:> wrapper()longname = 2> wrapper(longname = 3)longname = 3> wrapper(long=20)longname = 20> wrapper(junk=3)Error in lowlevel(longname = 2, junk = 3) : unused argument(s) (junk ...) -Deepayan