[Rd] suggestion: "." in [lsv]apply()
Henrik Bengtsson
henr|k@bengt@@on @end|ng |rom gm@||@com
Thu Apr 16 18:50:06 CEST 2020
I'm sure this exists elsewhere, but, as a trade-off, could you achieve
what you want with a separate helper function F(expr) that constructs
the function you want to pass to [lsv]apply()? Something that would
allow you to write:
sapply(split(mtcars, mtcars$cyl), F(summary(lm(mpg ~ wt,.))$r.squared))
Such an F() function would apply elsewhere too.
/Henrik
On Thu, Apr 16, 2020 at 9:30 AM Michael Mahoney
<mike.mahoney.218 using gmail.com> wrote:
>
> This syntax is already implemented in the {purrr} package, more or
> less -- you need to add a tilde before your function call for it to
> work exactly as written:
>
> purrr::map_dbl(split(mtcars, mtcars$cyl), ~ summary(lm(wt ~ mpg, .))$r.squared)
>
> is equivalent to
>
> sapply(split(mtcars, mtcars$cyl), function(d) summary(lm(mpg ~ wt,
> d))$r.squared)
>
> Seems like using this package is probably an easier solution for this
> wish than adding a reserved variable and adding additional syntax to
> the apply family as a whole.
>
> Thanks,
>
> -Mike
>
> > From: Sokol Serguei <sokol using insa-toulouse.fr>
> > Date: Thu, Apr 16, 2020 at 12:03 PM
> > Subject: Re: [Rd] suggestion: "." in [lsv]apply()
> > To: William Dunlap <wdunlap using tibco.com>
> > Cc: r-devel <r-devel using r-project.org>
> >
> >
> > 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]]
> >
> > ______________________________________________
> > R-devel using r-project.org mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-devel
>
> ______________________________________________
> R-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
More information about the R-devel
mailing list