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

2020-04-16 Thread Sokol Serguei

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(s) || is.call(s) && s[[1]]==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 mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Add a new environment variable switch for the 'large version' check

2020-04-16 Thread Dirk Eddelbuettel


Or you use a fourth component to signal a development version as Rcpp has
done for years (and, IIRC, for longer than devtools et al used '9000').

There is no functional difference between 1.2.3.1 and 1.2.3.9000. They are
both larger than 1.2.3 (in the package_version() sense) and signal an
intermediate version between 1.2.3 and 1.2.4.

But one requires a patch. ¯\_(ツ)_/¯.

Dirk

-- 
http://dirk.eddelbuettel.com | @eddelbuettel | e...@debian.org

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


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

2020-04-16 Thread Simon Urbanek
Serguei,


> On 17/04/2020, at 2:24 AM, Sokol Serguei  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.


It's not in any way "neater", not only is it less readable, it's just plain 
wrong. What if the expression returned a function? How do you know that you 
don't want to apply the result of the call? For the same reason the 
implementation below won't work - very often you just pass a symbol that 
evaluates to a function and always en expression that returns a function and 
there is no way to distinguish that from your new proposed syntax. When you 
feel compelled to use substitute() you should hear alarm bells that something 
is wrong ;).

You can certainly write a new function that uses a different syntax (and I'm 
sure someone has already done that in the package space), but what you propose 
is incompatible with *apply in R (and very much not R syntax).

Cheers,
Simon


> To illustrate a possible implementation, I propose a wrapper example for 
> sapply():
> 
> wsapply=function(l, fun, ...) {
> s=substitute(fun)
> if (is.name(s) || is.call(s) && s[[1]]==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 mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
> 

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


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

2020-04-16 Thread William Dunlap via R-devel
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


On Thu, Apr 16, 2020 at 7:25 AM Sokol Serguei 
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(s) || is.call(s) && s[[1]]==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 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


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

2020-04-16 Thread Sokol Serguei

Simon,

Thanks for replying. In what follows I won't try to argue (I understood 
that you find this a bad idea) but I would like to make clearer some of 
your point for me (and may be for others).


Le 16/04/2020 à 16:48, Simon Urbanek a écrit :

Serguei,
On 17/04/2020, at 2:24 AM, Sokol Serguei  
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. 
It's not in any way "neater", not only is it less readable, it's just 
plain wrong. What if the expression returned a function?

do you mean like in
l=sapply(1:3, function(i) function(x) i+x)
l[[1]](3)
# 4
l[[2]](3)
# 5

This is indeed a corner case but a pair of () or {} can keep wsapply() 
in course:

l=wsapply(1:3, (function(x) .+x))

l[[1]](3)

# 4

l[[2]](3)

# 5

How do you know that you don't want to apply the result of the call?
A small example (if it is significantly different from the one above) 
would be very helpful for me to understand this point.


For the same reason the implementation below won't work - very often 
you just pass a symbol that evaluates to a function and always en 
expression that returns a function and there is no way to distinguish 
that from your new proposed syntax.

Even with () or {} around such "dotted" expression?

Best,
Serguei.

When you feel compelled to use substitute() you should hear alarm 
bells that something is wrong ;). You can certainly write a new 
function that uses a different syntax (and I'm sure someone has 
already done that in the package space), but what you propose is 
incompatible with *apply in R (and very much not R syntax). Cheers, Simon
To illustrate a possible implementation, I propose a wrapper example 
for sapply(): wsapply=function(l, fun, ...) { s=substitute(fun) if 
(is.name(s) || is.call(s) && s[[1]]==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 mailing list 
https://stat.ethz.ch/mailman/listinfo/r-devel 




__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


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

2020-04-16 Thread Sokol Serguei
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 
>
>
> On Thu, Apr 16, 2020 at 7:25 AM Sokol Serguei  > 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 (s) || is.call(s) &&
> s[[1]]==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  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


Re: [Rd] Add a new environment variable switch for the 'large version' check

2020-04-16 Thread Henrik Bengtsson
I'd second Jim's feature request - it would be useful to be able to
disable this in CI and elsewhere.The concept of using an "unusual"
version component such as a very large number does a nice job of
indicating "unusual" and serves as a blocker for submitting
work-in-progress to CRAN by mistake (hence the validation in 'R CMD
check').

Another point, which I don't think Jim made, is that this would make
it possible to run R CMD check --as-cran on your work-in-progress and
get all OKs.  This in turn would allow us to trigger a non-zero exit
status also for NOTEs (not just ERRORs and WARNINGs).  Currently, the
warning on -9000 is a false positive in this sense.  This will allow
developers to be more conservative without risking to treat NOTEs as
something to expect as normal.  CI services are typically configured
to alert the developer on ERRORs and WARNINGs but, AFAIK, not on
NOTEs.

On the topic of unusual version numbers: I'd like to suggest that
CRAN(*) makes an unusual version bump whenever they orphan a package,
e.g. to suffix -1. CRAN already updates/modifies the package
tarball for orphaned packages by setting 'Maintainer: ORPHANED' in the
DESCRIPTION file. By also bumping the version of orphaned packages it
would it stand out in sessionInfo(), which helps in troubleshooting
and bug reports, etc.  But more importantly, the most recent stable
CRAN release remain untouched, which I think has a value by itself for
scientific purposes.

/Henrik

(*) Yes, I should email CRAN about this, but I think it's worth
vetting it here first.

On Thu, Apr 16, 2020 at 7:44 AM Dirk Eddelbuettel  wrote:
>
>
> Or you use a fourth component to signal a development version as Rcpp has
> done for years (and, IIRC, for longer than devtools et al used '9000').
>
> There is no functional difference between 1.2.3.1 and 1.2.3.9000. They are
> both larger than 1.2.3 (in the package_version() sense) and signal an
> intermediate version between 1.2.3 and 1.2.4.
>
> But one requires a patch. ¯\_(ツ)_/¯.
>
> Dirk
>
> --
> http://dirk.eddelbuettel.com | @eddelbuettel | e...@debian.org
>
> __
> R-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


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

2020-04-16 Thread Michael Mahoney
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 
> Date: Thu, Apr 16, 2020 at 12:03 PM
> Subject: Re: [Rd] suggestion: "." in [lsv]apply()
> To: William Dunlap 
> Cc: r-devel 
>
>
> 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 
> >
> >
> > On Thu, Apr 16, 2020 at 7:25 AM Sokol Serguei  > > 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 (s) || is.call(s) &&
> > s[[1]]==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  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

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


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

2020-04-16 Thread Henrik Bengtsson
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
 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 
> > Date: Thu, Apr 16, 2020 at 12:03 PM
> > Subject: Re: [Rd] suggestion: "." in [lsv]apply()
> > To: William Dunlap 
> > Cc: r-devel 
> >
> >
> > 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 
> > >
> > >
> > > On Thu, Apr 16, 2020 at 7:25 AM Sokol Serguei  > > > 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 (s) || is.call(s) &&
> > > s[[1]]==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  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
>
> __
> R-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


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

2020-04-16 Thread Voeten, C.C.
Such a helper already exists in magrittr, which allows you to compose anonymous 
functions like so:

library(magrittr)
sapply(1:10,. %>% add(4))

That said, I'm all for this being able to be shortened to sapply(1:10,add(.)), 
but that would require language support, as Serguei asks for. Languages such as 
Perl already have a similar construct (I'm thinking of Perl 5's $_). It would 
be nice if R would have such a feature as well. ". %>%" is still quite a 
mouthful---especially since percentage signs are quite visually salient, so 
they give the appearance of clutter while the whole construct seems intended to 
*simplify* such expressions and draw attention to the operation rather than the 
boilerplate.

Best,
Cesko

> -Original Message-
> From: R-devel  On Behalf Of Henrik
> Bengtsson
> Sent: Thursday, April 16, 2020 6:50 PM
> To: Michael Mahoney 
> Cc: R-devel 
> Subject: Re: [Rd] suggestion: "." in [lsv]apply()
> 
> 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
>  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 
> > > Date: Thu, Apr 16, 2020 at 12:03 PM
> > > Subject: Re: [Rd] suggestion: "." in [lsv]apply()
> > > To: William Dunlap 
> > > Cc: r-devel 
> > >
> > >
> > > 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 
> > > >
> > > >
> > > > On Thu, Apr 16, 2020 at 7:25 AM Sokol Serguei  > > > > 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 (s) || is.call(s) &&
> > > > s[[1]]==as.name ("function")) {
> > > >  sapply(l, fun, ...) # legacy call
> > > >  } else {
> > > >  sapply(l, function(d) eval(s, list(

[Rd] Read.Spss use $variable.labels as attributes instead of read/write.dta's $var.labels

2020-04-16 Thread Ellie Chen
Hi,

I notice that read.spss store variables' labels into df's attributes
as $variable.labels, while write.dta read df's attribute $var.labels as
variable labels. This becomes a problem when I try to convert a bulk of
SPSS's por files into STATA's dta format using these commands. The data
were successfully imported but write.dta couldn't read variable labels due
to the inconsistency. This problem is solved after adding $var.labels into
df's attributes.

I think it will be great if write.dta can read either $var.labels or
$variable.labels as variable labels. What do you think?

Best,
Ellie

[[alternative HTML version deleted]]

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


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

2020-04-16 Thread Sokol Serguei

Thanks Henrik,

Probably, it will be the solution I'll retain.

Best,
Serguei.

Le 16/04/2020 à 18:50, Henrik Bengtsson a écrit :

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
 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 
Date: Thu, Apr 16, 2020 at 12:03 PM
Subject: Re: [Rd] suggestion: "." in [lsv]apply()
To: William Dunlap 
Cc: r-devel 


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 


On Thu, Apr 16, 2020 at 7:25 AM Sokol Serguei 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 (s) || is.call(s) &&
 s[[1]]==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  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

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


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

2020-04-16 Thread Simon Urbanek
Sergei,

the main problem that I was pointing out is is that there is no way you can 
introduce the new syntax without breaking the old one. The expression is 
evaluated to obtain a function, so by definition using anything that results in 
a valid expression for your syntax will break. E.g., using sapply(x, (foo)) is 
completely valid so you can't just change the evaluation of the expression to 
something different (which is what you're doing). As people were pointing out 
there are many ways to do this if you change the syntax.

I'm not arguing against the principle, I'm arguing about your particular 
proposal as it is inconsistent and not general. Personally, I find the current 
syntax much clearer and readable (defining anything by convention like . being 
the function variable seems arbitrary and "dirty" to me), but if you wanted to 
define a shorter syntax, you could use something like x ~> i + x. That said, I 
really don't see the value of not using function(x) [especially these days when 
people are arguing for long variable names with the justification that IDEs do 
all the work anyway], but as I said, my argument was against the actual 
proposal, not general ideas about syntax improvement.

Cheers,
Simon


> On 17/04/2020, at 3:53 AM, Sokol Serguei  wrote:
> 
> Simon,
> 
> Thanks for replying. In what follows I won't try to argue (I understood that 
> you find this a bad idea) but I would like to make clearer some of your point 
> for me (and may be for others).
> 
> Le 16/04/2020 à 16:48, Simon Urbanek a écrit :
>> Serguei,
>>> On 17/04/2020, at 2:24 AM, Sokol Serguei  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. 
>> It's not in any way "neater", not only is it less readable, it's just plain 
>> wrong. What if the expression returned a function?
> do you mean like in
> l=sapply(1:3, function(i) function(x) i+x)
> l[[1]](3)
> # 4
> l[[2]](3)
> # 5
> 
> This is indeed a corner case but a pair of () or {} can keep wsapply() in 
> course:
> l=wsapply(1:3, (function(x) .+x))
> 
> l[[1]](3)
> 
> # 4
> 
> l[[2]](3)
> 
> # 5
>> How do you know that you don't want to apply the result of the call?
> A small example (if it is significantly different from the one above) would 
> be very helpful for me to understand this point.
> 
>> For the same reason the implementation below won't work - very often you 
>> just pass a symbol that evaluates to a function and always en expression 
>> that returns a function and there is no way to distinguish that from your 
>> new proposed syntax.
> Even with () or {} around such "dotted" expression?
> 
> Best,
> Serguei.
> 
>> When you feel compelled to use substitute() you should hear alarm bells that 
>> something is wrong ;). You can certainly write a new function that uses a 
>> different syntax (and I'm sure someone has already done that in the package 
>> space), but what you propose is incompatible with *apply in R (and very much 
>> not R syntax). Cheers, Simon
>>> To illustrate a possible implementation, I propose a wrapper example for 
>>> sapply(): wsapply=function(l, fun, ...) { s=substitute(fun) if (is.name(s) 
>>> || is.call(s) && s[[1]]==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 
>>> mailing list https://stat.ethz.ch/mailman/listinfo/r-devel 
>> 
> 

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Add a new environment variable switch for the 'large version' check

2020-04-16 Thread Jan Gorecki
For the same reason, handling false positive in CRAN checks, there are
other places that could be improved.
Like "size of tarball" NOTE.
If one could control this size with an environment variable. Similarly
to the proposal made by Jim. It would be useful as well.

On Thu, Apr 16, 2020 at 5:06 PM Henrik Bengtsson
 wrote:
>
> I'd second Jim's feature request - it would be useful to be able to
> disable this in CI and elsewhere.The concept of using an "unusual"
> version component such as a very large number does a nice job of
> indicating "unusual" and serves as a blocker for submitting
> work-in-progress to CRAN by mistake (hence the validation in 'R CMD
> check').
>
> Another point, which I don't think Jim made, is that this would make
> it possible to run R CMD check --as-cran on your work-in-progress and
> get all OKs.  This in turn would allow us to trigger a non-zero exit
> status also for NOTEs (not just ERRORs and WARNINGs).  Currently, the
> warning on -9000 is a false positive in this sense.  This will allow
> developers to be more conservative without risking to treat NOTEs as
> something to expect as normal.  CI services are typically configured
> to alert the developer on ERRORs and WARNINGs but, AFAIK, not on
> NOTEs.
>
> On the topic of unusual version numbers: I'd like to suggest that
> CRAN(*) makes an unusual version bump whenever they orphan a package,
> e.g. to suffix -1. CRAN already updates/modifies the package
> tarball for orphaned packages by setting 'Maintainer: ORPHANED' in the
> DESCRIPTION file. By also bumping the version of orphaned packages it
> would it stand out in sessionInfo(), which helps in troubleshooting
> and bug reports, etc.  But more importantly, the most recent stable
> CRAN release remain untouched, which I think has a value by itself for
> scientific purposes.
>
> /Henrik
>
> (*) Yes, I should email CRAN about this, but I think it's worth
> vetting it here first.
>
> On Thu, Apr 16, 2020 at 7:44 AM Dirk Eddelbuettel  wrote:
> >
> >
> > Or you use a fourth component to signal a development version as Rcpp has
> > done for years (and, IIRC, for longer than devtools et al used '9000').
> >
> > There is no functional difference between 1.2.3.1 and 1.2.3.9000. They are
> > both larger than 1.2.3 (in the package_version() sense) and signal an
> > intermediate version between 1.2.3 and 1.2.4.
> >
> > But one requires a patch. ¯\_(ツ)_/¯.
> >
> > Dirk
> >
> > --
> > http://dirk.eddelbuettel.com | @eddelbuettel | e...@debian.org
> >
> > __
> > R-devel@r-project.org mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-devel
>
> __
> R-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel