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 ...
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
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 260 bytes
Desc: OpenPGP digital signature
URL:
<https://stat.ethz.ch/pipermail/r-devel/attachments/20090606/7daebbbd/attachment.bin>
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