[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