[R] Fine controlling "three dots" argument dispatch to functions with identical argument names

Jeff Newmiller jdnewmil at dcn.davis.CA.us
Sat Nov 15 17:26:29 CET 2014


AFAIK You have to alter the name of at least one of the y arguments as used by foobar, and anyone calling foobar has to read about that in the help file. That is only one y can be in "...". e.g.

foobar <- function( x, y_foo, ... ) {
  foo( x, y=y_foo, ... )
  bar( x, ... )
}


---------------------------------------------------------------------------
Jeff Newmiller                        The     .....       .....  Go Live...
DCN:<jdnewmil at dcn.davis.ca.us>        Basics: ##.#.       ##.#.  Live Go...
                                      Live:   OO#.. Dead: OO#..  Playing
Research Engineer (Solar/Batteries            O.O#.       #.O#.  with
/Software/Embedded Controllers)               .OO#.       .OO#.  rocks...1k
--------------------------------------------------------------------------- 
Sent from my phone. Please excuse my brevity.

On November 15, 2014 6:49:41 AM PST, Janko Thyson <janko.thyson at gmail.com> wrote:
>Dear list,
>
>I wonder if there's a clever way to fine control the exact way
>arguments
>are dispatched via R's "three dots" argument ....
>
>Consider the following use case:
>
>- you have a function foobar() that calls foo() which in turn calls
>bar()
>- *both* foo() and bar() have an argument that's called y, but they
>each
>   have a *different meaning*
>- in the call to foobar(), you would like to say "here's the y for
>foo()
> and here's the y for bar()". *That's what I would like to accomplish*.
>
>If you simply call foobar(x = "John Doe", y = "hello world"), y only
>get's
>dispatched to foo() as in the call to bar() things would have to be
>explicit in order to be dispatched (i.e. the call would have to be
>bar(x =
>x, y = y) instead of bar(x = x, ...):
>
>foo <- function(x, y = "some character", ...) {
>  message("foo ----------")
>  message("foo/threedots")
>  try(print(list(...)))
>  message("foo/y")
>  try(print(y))
>  bar(x = x, ...)}
>bar <- function(x, y = TRUE, ...) {
>  message("bar ----------")
>  message("bar/threedots")
>  try(print(list(...)))
>  message("bar/y")
>  try(print(y))
>  return(paste0("hello: ", x))}
>foobar <- function(x, ...) {
>  message("foobar ----------")
>  message("foobar/threedots")
>  try(print(list(...)))
>  foo(x = x, ...)}
>
>foobar(x = "John Doe", y = "hi there")# foobar ----------#
>foobar/threedots# $y# [1] "hi there"# # foo ----------# foo/threedots#
>list()# foo/y# [1] "hi there"# bar ----------# bar/threedots# list()#
>bar/y# [1] TRUE# [1] "hello: John Doe"
>
>What I conceptionally would like to be able to do is something like
>this:
>
>foobar(x = "John Doe", y_foo = "hello world!", y_bar = FALSE)
>
>Here's an approach that works but that also feels very odd:
>
>foo <- function(x, y = "some character", ...) {
>  message("foo ----------")
>  message("foo/threedots")
>  try(print(list(...)))
>  message("foo/y")
>  arg <- paste0("y_", sys.call()[[1]])
>  if (arg %in% names(list(...))) {
>    y <- list(...)[[arg]]
>  }
>  try(print(y))
>  bar(x = x, ...)}
>bar <- function(x, y = TRUE, ...) {
>  message("bar ----------")
>  message("bar/threedots")
>  try(print(list(...)))
>  message("bar/y")
>  arg <- paste0("y_", sys.call()[[1]])
>  if (arg %in% names(list(...))) {
>    y <- list(...)[[arg]]
>  }
>  try(print(y))
>  return(paste0("hello: ", x))}
>
>foobar(x = "John Doe", y_foo = "hello world!", y_bar = FALSE)# foobar
>----------# foobar/threedots# $y_foo# [1] "hello world!"# # $y_bar#
>[1] FALSE# # foo ----------# foo/threedots# $y_foo# [1] "hello
>world!"# # $y_bar# [1] FALSE# # foo/y# [1] "hello world!"# bar
>----------# bar/threedots# $y_foo# [1] "hello world!"# # $y_bar# [1]
>FALSE# # bar/y# [1] FALSE# [1] "hello: John Doe"
>
>How would you go about implementing something like this?
>
>I also played around with S4 method dispatch to see if I could define
>methods for a signature argument ..., but that didn't go too well (and
>it's
>probably a very bad idea anyway):
>
>setGeneric(
>  name = "foo",
>  signature = c("x", "..."),
>  def = function(x, ...) standardGeneric("foo")      )
>setMethod(
>  f = "foo",
>  signature = signature(x = "character", "..." = "MyThreeDotsForBar"),
> definition = function(x, ...) bar(x = x))## --> does not work
>
>	[[alternative HTML version deleted]]
>
>______________________________________________
>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.



More information about the R-help mailing list