Barry Rowlingson
2017-Mar-27 15:21 UTC
[Rd] A trap for young players with the lapply() function.
On Mon, Mar 27, 2017 at 1:17 AM, Rolf Turner <r.turner at auckland.ac.nz> wrote:> > Is there any way to trap/detect the use of an optional argument called > "X" and thereby issue a more perspicuous error message? > > This would be helpful to those users who, like myself, are bears of very > little brain. > > Failing that (it does look impossible)You can get the names of named arguments: > z = function(x,X){cos(x*X)} > names(formals(z)) [1] "x" "X"> might it not be a good idea to > add a warning to the help for lapply(), to the effect that if FUN has an > optional argument named "X" then passing this argument via "..." will > cause this argument to be taken as the first argument to lapply() and > thereby induce an error?Another idea might be to use purrr:map instead, which is quite happy with X in your function: > xxx <- purrr::map(y,function(x,X){cos(x*X)},X=2*pi) > xxx [[1]] [1] 0.08419541 [[2]] [1] 0.6346404 [[3]] [1] 0.9800506 [[4]] [1] 0.8686734 [[5]] [1] -0.9220073 But don't feed `.x` to your purrrring cats, or fails silently: > xxx <- purrr::map(y,function(x,.x){cos(x*.x)},.x=2*pi) > xxx [[1]] NULL But who would have a function with `.x` as an argument?> ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel
Rolf Turner
2017-Mar-27 21:26 UTC
[Rd] A trap for young players with the lapply() function.
On 28/03/17 04:21, Barry Rowlingson wrote:> On Mon, Mar 27, 2017 at 1:17 AM, Rolf Turner <r.turner at auckland.ac.nz> wrote: >> >> Is there any way to trap/detect the use of an optional argument called >> "X" and thereby issue a more perspicuous error message? >> >> This would be helpful to those users who, like myself, are bears of very >> little brain. >> >> Failing that (it does look impossible) > > You can get the names of named arguments: > > > z = function(x,X){cos(x*X)} > > names(formals(z)) > [1] "x" "X"That doesn't seem to help. I tried putting a browser inside lapply() and looked at formals(FUN). This gave NULL, because FUN has already been taken to be the list argument "x" to which lapply() is being applied.>> might it not be a good idea to >> add a warning to the help for lapply(), to the effect that if FUN has an >> optional argument named "X" then passing this argument via "..." will >> cause this argument to be taken as the first argument to lapply() and >> thereby induce an error? > > Another idea might be to use purrr:map instead, which is quite happy > with X in your function: > > > xxx <- purrr::map(y,function(x,X){cos(x*X)},X=2*pi) > > xxx > [[1]] > [1] 0.08419541 > > [[2]] > [1] 0.6346404 > > [[3]] > [1] 0.9800506 > > [[4]] > [1] 0.8686734 > > [[5]] > [1] -0.9220073 > > But don't feed `.x` to your purrrring cats, or fails silently: > > > xxx <- purrr::map(y,function(x,.x){cos(x*.x)},.x=2*pi) > > xxx > [[1]] > NULL > > But who would have a function with `.x` as an argument?Indeed. It struck me that a possible workaround would be to change the name of the first argument of lapply() from "X" to ".X". No-one would have a function with an argument names ".X" --- at least I wouldn't, so this would solve the problem for me. It seems to me that this change could be made without breaking anything. But perhaps I am engaging in my usual PollyAnna-ish optimism! :-) cheers, Rolf -- Technical Editor ANZJS Department of Statistics University of Auckland Phone: +64-9-373-7599 ext. 88276
Enrico Schumann
2017-Mar-29 07:32 UTC
[Rd] A trap for young players with the lapply() function.
(inline) On Tue, 28 Mar 2017, Rolf Turner writes:> On 28/03/17 04:21, Barry Rowlingson wrote: >> On Mon, Mar 27, 2017 at 1:17 AM, Rolf Turner <r.turner at auckland.ac.nz> wrote: >>> >>> Is there any way to trap/detect the use of an optional argument called >>> "X" and thereby issue a more perspicuous error message? >>> >>> This would be helpful to those users who, like myself, are bears of very >>> little brain. >>> >>> Failing that (it does look impossible) >> >> You can get the names of named arguments: >> >> > z = function(x,X){cos(x*X)} >> > names(formals(z)) >> [1] "x" "X" > > That doesn't seem to help. I tried putting a browser inside lapply() > and looked at formals(FUN). This gave NULL, because FUN has already > been taken to be the list argument "x" to which lapply() is being > applied.You can get the call, without the arguments being matched, with `sys.call`. In your call of lapply, saying `sys.call()` before anything else would give you lapply(y, function(x, X) { cos(x * X) }, X = 2 * pi) which would allow you to get at the argument names of your function. if ("X" %in% names(sys.call()[[3L]][[2L]])) warnings("found 'X'") But more would be needed: you need to figure out which argument you actually meant to be FUN. (In the above, I simply assumed it was the second passed argument.) That is, you would need to figure out which passed argument is a function, which is not safe either, since ... may also contain functions.>>> might it not be a good idea to >>> add a warning to the help for lapply(), to the effect that if FUN has an >>> optional argument named "X" then passing this argument via "..." will >>> cause this argument to be taken as the first argument to lapply() and >>> thereby induce an error? >> >> Another idea might be to use purrr:map instead, which is quite happy >> with X in your function: >> >> > xxx <- purrr::map(y,function(x,X){cos(x*X)},X=2*pi) >> > xxx >> [[1]] >> [1] 0.08419541 >> >> [[2]] >> [1] 0.6346404 >> >> [[3]] >> [1] 0.9800506 >> >> [[4]] >> [1] 0.8686734 >> >> [[5]] >> [1] -0.9220073 >> >> But don't feed `.x` to your purrrring cats, or fails silently: >> >> > xxx <- purrr::map(y,function(x,.x){cos(x*.x)},.x=2*pi) >> > xxx >> [[1]] >> NULL >> >> But who would have a function with `.x` as an argument? > > Indeed. It struck me that a possible workaround would be to change > the name of the first argument of lapply() from "X" to ".X". No-one > would have a function with an argument names ".X" --- at least I > wouldn't, so this would solve the problem for me. > > It seems to me that this change could be made without breaking anything. > But perhaps I am engaging in my usual PollyAnna-ish optimism! :-) > > cheers, > > Rolf-- Enrico Schumann Lucerne, Switzerland http://enricoschumann.net
Possibly Parallel Threads
- A trap for young players with the lapply() function.
- A trap for young players with the lapply() function.
- A trap for young players with the lapply() function.
- A trap for young players with the lapply() function.
- A trap for young players with the lapply() function.