Thanks Bill, Clearly, my first proposition for wsapply() is quick and dirty one. However, if "." becomes a reserved variable with this new syntax, wsapply() can be fixed (at least for your example and alike) as:
wsapply=function(l, fun, ...) { .=substitute(fun) if (is.name(.) || is.call(.) && .[[1]]==as.name("function")) { sapply(l, fun, ...) } else { sapply(l, function(d) eval(., list(.=d)), ...) } } Will it do the job? Best, Serguei. Le 16/04/2020 à 17:07, William Dunlap a écrit : > Passing in a function passes not only an argument list but also an > environment from which to get free variables. Since your function > doesn't pay attention to the environment you get things like the > following. > > > wsapply(list(1,2:3), paste(., ":", deparse(s))) > [[1]] > [1] "1 : paste(., \":\", deparse(s))" > > [[2]] > [1] "2 : paste(., \":\", deparse(s))" "3 : paste(., \":\", deparse(s))" > > Bill Dunlap > TIBCO Software > wdunlap tibco.com <http://tibco.com> > > > On Thu, Apr 16, 2020 at 7:25 AM Sokol Serguei <so...@insa-toulouse.fr > <mailto:so...@insa-toulouse.fr>> wrote: > > Hi, > > I would like to make a suggestion for a small syntactic > modification of > FUN argument in the family of functions [lsv]apply(). The idea is to > allow one-liner expressions without typing "function(item) {...}" to > surround them. The argument to the anonymous function is simply > referred > as ".". Let take an example. With this new feature, the following call > > sapply(split(mtcars, mtcars$cyl), function(d) summary(lm(mpg ~ wt, > d))$r.squared) > # 4 6 8 > #0.5086326 0.4645102 0.4229655 > > > could be rewritten as > > sapply(split(mtcars, mtcars$cyl), summary(lm(mpg ~ wt, .))$r.squared) > > "Not a big saving in typing" you can say but multiplied by the > number of > [lsv]apply usage and a neater look, I think, the idea merits to be > considered. > To illustrate a possible implementation, I propose a wrapper > example for > sapply(): > > wsapply=function(l, fun, ...) { > s=substitute(fun) > if (is.name <http://is.name>(s) || is.call(s) && > s[[1]]==as.name <http://as.name>("function")) { > sapply(l, fun, ...) # legacy call > } else { > sapply(l, function(d) eval(s, list(.=d)), ...) > } > } > > Now, we can do: > > wsapply(split(mtcars, mtcars$cyl), summary(lm(mpg ~ wt, .))$r.squared) > > or, traditional way: > > wsapply(split(mtcars, mtcars$cyl), function(d) summary(lm(mpg ~ wt, > d))$r.squared) > > the both work. > > How do you feel about that? > > Best, > Serguei. > > ______________________________________________ > R-devel@r-project.org <mailto:R-devel@r-project.org> mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > [[alternative HTML version deleted]] ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel