On Mon, Mar 21, 2011 at 2:53 PM, Gabor Grothendieck <ggrothendi...@gmail.com > wrote:
> On Mon, Mar 21, 2011 at 8:46 AM, Kenn Konstabel <lebats...@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]] ______________________________________________ R-help@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.