[Rd] suggestion: "." in [lsv]apply()

Sokol Serguei @oko| @end|ng |rom |n@@-tou|ou@e@|r
Thu Apr 16 18:02:43 CEST 2020


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 <sokol using insa-toulouse.fr 
> <mailto:sokol using 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 using r-project.org <mailto:R-devel using r-project.org> mailing list
>     https://stat.ethz.ch/mailman/listinfo/r-devel
>


	[[alternative HTML version deleted]]



More information about the R-devel mailing list