On Mon, Mar 21, 2011 at 2:53 PM, Gabor Grothendieck <ggrothendieck@gmail.com
> wrote:

> On Mon, Mar 21, 2011 at 8:46 AM, Kenn Konstabel <lebatsnok@gmail.com>
> wrote:
> > Dear all,
> >
> > I sometimes use the following function:
> >
> > Curry <- function(FUN,...) {
> >   # by Byron Ellis,
> > https://stat.ethz.ch/pipermail/r-devel/2007-November/047318.html
> >   .orig <- list(...)
> >   function(...) do.call(FUN,c(.orig,list(...)))
> >   }
> >
> > ... and have thought it might be convenient to have a method for [ doing
> > this. As a simple example,
> >
> >> apply(M, 1, mean[trim=0.1])  # hypothetical equivalent to apply(M, 1,
> > Curry(mean, trim=0.1))
> >
> >  would be easier to understand  than passing arguments by ...
> >
> >> apply(M, 1, mean, trim=0.1)
> >
> > and much shorter than using an anonymous function
> >
> >> apply(M, 1, function(x) mean(x, trim=0.1)
> >
> > This would be much more useful for complicated functions that may take
> > several functions as arguments. For example (my real examples are too
> long
> > but this seems general enough),
> >
> > foo <- function(x, ...) {
> >     dots <- list(...)
> >     mapply(function(f) f(x), dots)
> >     }
> >
> > foo(1:10, mean, sd)
> > foo(c(1:10, NA), mean, mean[trim=0.1, na.rm=TRUE], sd[na.rm=TRUE])
> >
> > Defining `[.function` <- Curry won't help:
> >
> >> mean[trim=0.1]
> > Error in mean[trim = 0.1] : object of type 'closure' is not subsettable
> >
> > One can write summary and other methods for class "function" without such
> > problems, so this has something to do with [ being a primitive function
> and
> > not using UseMethod, it would be foolish to re-define it as an "ordinary"
> > generic function.
> >
> > Redefining mean as structure(mean, class="function") will make it work
> but
> > then one would have to do it for all functions which is not feasible.
> >
> >> class(mean) <- class(mean)
> >> class(sd)<-class(sd)
> >> foo(c(1:10, NA), mean, mean[na.rm=TRUE], mean[trim=0.1, na.rm=TRUE],
> > sd[na.rm=TRUE])
> > [1]       NA 5.500000 5.500000 3.027650
> >
> > Or one could define a short-named function (say, .) doing this:
> >
> >> rm(mean, sd) ## removing the modified copies from global environment
> >> .<-function(x) structure(x, class=class(x))
> >> foo(c(1:10, NA), mean, .(mean)[na.rm=TRUE], .(mean)[trim=0.1,
> na.rm=TRUE],
> > .(sd)[na.rm=TRUE])
> >
> > But this is not as nice. (And neither is replacing "[" with "Curry" by
> using
> > substitute et al. inside `foo`, - this would make it usable only within
> > functions that one could be bothered to redefine this way - probably
> none.)
> >
> > Thanks in advance for any ideas and comments (including the ones saying
> that
> > this is an awful idea)
>
> If the aim is to find some short form to express functions then
> gsubfn's fn$ construct provides a way. It allows you to specify
> functions using formula notation.  The left hand side of the formula
> is the arguments and the right hand side is the body.  If no args are
> specified then it uses the free variables in the body in the order
> encountered to form the args.  Thus one could write the following.
> (Since no args were specified and the right hand side uses the free
> variable x it assumes that there is a single arg x.)
>
> library(gsubfn)
> fn$apply(longley, 2, ~ mean(x, trim = 0.1))
> fn$lapply(longley, ~ mean(x, trim = 0.1))
> fn$sapply(longley, ~ mean(x, trim = 0.1))
>
> fn$ can preface just about any function.  It does not have to be one
> of the above.  See ?fn and http://gsubfn.googlecode.com for more info.
>
>
Thanks a lot! This is not exactly what I meant but it's a very useful hint.
The idea was to find a concise way of using function with different default
values for some of the arguments or to "fix" some of the arguments so that
the result is a unary function.

I couldn't find a way to do it with gsubfn package directly (although maybe
I should have another look) but by stealing some of your ideas:

. <- structure(NA, class="rice")
`$.rice` <- function(x,y) structure(match.fun(y), class="function")
`[.function` <- function(FUN,...) {
   # https://stat.ethz.ch/pipermail/r-devel/2007-November/047318.html
   .orig <- list(...)
   function(...) do.call(FUN,c(.orig,list(...)))
   }

.$mean[trim=0.1](c(0:99,1e+20))
# 50

Thanks again,





> --
> Statistics & Software Consulting
> GKX Group, GKX Associates Inc.
> tel: 1-877-GKX-GROUP
> email: ggrothendieck at gmail.com
>

	[[alternative HTML version deleted]]

