From ripley at stats.ox.ac.uk  Wed Jun 10 16:01:26 2009
From: ripley at stats.ox.ac.uk (Prof Brian Ripley)
Date: Wed, 10 Jun 2009 15:01:26 +0100 (BST)
Subject: [Rd] Reduce: extra args wishlist?
In-Reply-To: <4A2AF18D.8030805@ufl.edu>
References: <4A2AF18D.8030805@ufl.edu>
Message-ID: <alpine.LFD.2.00.0906101454580.22065@gannet.stats.ox.ac.uk>

On Sat, 6 Jun 2009, Ben Bolker wrote:

>
>  Is there a reason that Reduce() doesn't take a "..." argument that
> would allow arbitrary extra arguments to be passed through to the function?
>
>  Here is a little example of how this would be convenient:
>
> z <- list(
>          data.frame(state=c("California"),
>                     cases=0),
>          data.frame(state=c("California","Massachusetts"),
>                     cases=c(1,2)),
>          data.frame(state=c("California","Massachusetts","Arizona"),
>                     cases=c(1,2,17)))
>
> ## read in revised version of Reduce()
> Reduce(merge,z,by="state",all=TRUE)
>
>  The change is simple -- just add "..." to every call to the function
> in Reduce() --  patch is included below my signature ...
>
>  It's not a big deal -- I could also do
> Reduce(function(x,y) { merge(x,y,by="state",all=TRUE) }, z)
> but there doesn't seem to be a good reason not to allow it ...

I think the idiom of the languages from which this comes would indeed 
to be use an anonymous function, and in R to use ... and no braces, as 
in

Reduce(function(...) merge(..., by="state", all=TRUE), z)

But that's not the (ony) R idiom, so I am happy to add a ... argument 
to Reduce.  Unfortunately the patch below is backwards (you have diffs 
from old to new in 'patch' format), and we do need to patch the 
documentation (which gets a bit ugly as ... has a different meaning 
for another function on the Reduce help page).  I think I have sorted 
these out, and will commit to R-devel shortly.

>
>  cheers
>    Ben Bolker
>
>
> -- 
> Ben Bolker
> Associate professor, Biology Dep't, Univ. of Florida
> bolker at ufl.edu / www.zoology.ufl.edu/bolker
> GPG key: www.zoology.ufl.edu/bolker/benbolker-publickey.asc
>
>
> *** /home/ben/funprog.R.new	2009-06-06 18:30:56.000000000 -0400
> --- src/library/base/R/funprog.R	2009-02-12 10:39:32.000000000 -0500
> ***************
> *** 15,21 ****
>  #  http://www.r-project.org/Licenses/
>
>  Reduce <-
> ! function(f, x, init, right = FALSE, accumulate = FALSE, ...)
>  {
>      mis <- missing(init)
>      len <- length(x)
> --- 15,21 ----
>  #  http://www.r-project.org/Licenses/
>
>  Reduce <-
> ! function(f, x, init, right = FALSE, accumulate = FALSE)
>  {
>      mis <- missing(init)
>      len <- length(x)
> ***************
> *** 47,57 ****
>      if(!accumulate) {
>          if(right) {
>              for(i in rev(ind))
> !                 init <- f(x[[i]], init, ...)
>          }
>          else {
>              for(i in ind)
> !                 init <- f(init, x[[i]], ...)
>          }
>          init
>      }
> --- 47,57 ----
>      if(!accumulate) {
>          if(right) {
>              for(i in rev(ind))
> !                 init <- f(x[[i]], init)
>          }
>          else {
>              for(i in ind)
> !                 init <- f(init, x[[i]])
>          }
>          init
>      }
> ***************
> *** 64,76 ****
>              if(right) {
>                  out[[len]] <- init
>                  for(i in rev(ind)) {
> !                     init <- f(x[[i]], init, ...)
>                      out[[i]] <- init
>                  }
>              } else {
>                  out[[1L]] <- init
>                  for(i in ind) {
> !                     init <- f(init, x[[i]], ...)
>                      out[[i]] <- init
>                  }
>              }
> --- 64,76 ----
>              if(right) {
>                  out[[len]] <- init
>                  for(i in rev(ind)) {
> !                     init <- f(x[[i]], init)
>                      out[[i]] <- init
>                  }
>              } else {
>                  out[[1L]] <- init
>                  for(i in ind) {
> !                     init <- f(init, x[[i]])
>                      out[[i]] <- init
>                  }
>              }
> ***************
> *** 78,91 ****
>              if(right) {
>                  out[[len]] <- init
>                  for(i in rev(ind)) {
> !                     init <- f(x[[i]], init, ...)
>                      out[[i]] <- init
>                  }
>              }
>              else {
>                  for(i in ind) {
>                      out[[i]] <- init
> !                     init <- f(init, x[[i]], ...)
>                  }
>                  out[[len]] <- init
>              }
> --- 78,91 ----
>              if(right) {
>                  out[[len]] <- init
>                  for(i in rev(ind)) {
> !                     init <- f(x[[i]], init)
>                      out[[i]] <- init
>                  }
>              }
>              else {
>                  for(i in ind) {
>                      out[[i]] <- init
> !                     init <- f(init, x[[i]])
>                  }
>                  out[[len]] <- init
>              }
>
>
>

-- 
Brian D. Ripley,                  ripley at stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595



[Rd] Reduce: extra args wishlist?
Prof Brian Ripley