Rolf Turner
2017-Mar-28 21:30 UTC
[Rd] A trap for young players with the lapply() function.
On 28/03/17 15:26, Charles C. Berry wrote:> On Mon, 27 Mar 2017, Rolf Turner wrote: > >> >> From time to time I get myself into a state of bewilderment when using >> apply() by calling it with FUN equal to a function which has an >> "optional" argument named "X". >> >> E.g. >> >> xxx <- lapply(y,function(x,X){cos(x*X)},X=2*pi) >> >> which produces the error message >> >>> Error in get(as.character(FUN), mode = "function", envir = envir) : >>> object 'y' of mode 'function' was not found >> >> This of course happens because the name of the first argument of >> lapply() is "X" and so it takes the value of this first argument to be >> the supplied X (2*pi in the foregoing example) and then expects what >> the user has denoted by "y" to be the value of FUN, and (obviously!) >> it isn't. >> > > The lapply help page addresses this issue in `Details' : > > "it is good practice to name the first two arguments X and FUN if ... is > passed through: this both avoids partial matching to FUN and ensures > that a sensible error message is given if arguments named X or FUN are > passed through ..." > > So that advice suggests something like: > > xxx <- lapply( X=y, FUN=function(X,x){cos(X*x)}, x=2*pi )That is of course very sound advice, but it pre-supposes that the user is *aware* that there is a pitfall to be avoided. I was hoping for something that would protect dweebs like myself from the pitfall given that we are too obtuse to be cognizant of its existence. I think that the suggestion I made, in response to a posting by Barry Rowlingson, that the first argument of lapply() be given the name of ".X" rather than just-plain-X, would be (a) effective, and (b) harmless. cheers, Rolf -- Technical Editor ANZJS Department of Statistics University of Auckland Phone: +64-9-373-7599 ext. 88276
William Dunlap
2017-Mar-28 22:03 UTC
[Rd] A trap for young players with the lapply() function.
>I think that the suggestion I made, in response to a posting by Barry >Rowlingson, that the first argument of lapply() be given the name of ".X" rather >than just-plain-X, would be (a) effective, and (b) harmless.It would break any call to *apply() that used X= to name the first argument. There are currently 3020 such calls in the R code in CRAN. One can avoid the problem by creating the function given as the FUN argument when one calls lapply() and the like. Don't give that function arguments named "X", "FUN", "USE.NAMES", etc. and perhaps make use of R's lexical scoping to avoid having to use many arguments to the function. E.g., instead of sapply(1:5, sin) use sapply(1:5, function(theta) sin(theta)) or instead of myY <- 3 sapply(1:5, atan2, y=myY) use myY <- 3 sapply(1:5, function(x) atan2(myY, x)) Bill Dunlap TIBCO Software wdunlap tibco.com On Tue, Mar 28, 2017 at 2:30 PM, Rolf Turner <r.turner at auckland.ac.nz> wrote:> On 28/03/17 15:26, Charles C. Berry wrote: >> >> On Mon, 27 Mar 2017, Rolf Turner wrote: >> >>> >>> From time to time I get myself into a state of bewilderment when using >>> apply() by calling it with FUN equal to a function which has an >>> "optional" argument named "X". >>> >>> E.g. >>> >>> xxx <- lapply(y,function(x,X){cos(x*X)},X=2*pi) >>> >>> which produces the error message >>> >>>> Error in get(as.character(FUN), mode = "function", envir = envir) : >>>> object 'y' of mode 'function' was not found >>> >>> >>> This of course happens because the name of the first argument of >>> lapply() is "X" and so it takes the value of this first argument to be >>> the supplied X (2*pi in the foregoing example) and then expects what >>> the user has denoted by "y" to be the value of FUN, and (obviously!) >>> it isn't. >>> >> >> The lapply help page addresses this issue in `Details' : >> >> "it is good practice to name the first two arguments X and FUN if ... is >> passed through: this both avoids partial matching to FUN and ensures >> that a sensible error message is given if arguments named X or FUN are >> passed through ..." >> >> So that advice suggests something like: >> >> xxx <- lapply( X=y, FUN=function(X,x){cos(X*x)}, x=2*pi ) > > > > That is of course very sound advice, but it pre-supposes that the user is > *aware* that there is a pitfall to be avoided. I was hoping for something > that would protect dweebs like myself from the pitfall given that we are too > obtuse to be cognizant of its existence. > > I think that the suggestion I made, in response to a posting by Barry > Rowlingson, that the first argument of lapply() be given the name of ".X" > rather than just-plain-X, would be (a) effective, and (b) harmless. > > cheers, > > Rolf > > -- > Technical Editor ANZJS > Department of Statistics > University of Auckland > Phone: +64-9-373-7599 ext. 88276 > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel
Rolf Turner
2017-Mar-29 04:04 UTC
[Rd] A trap for young players with the lapply() function.
On 29/03/17 11:03, William Dunlap wrote:>> I think that the suggestion I made, in response to a posting by >> Barry Rowlingson, that the first argument of lapply() be given the name of >> ".X" rather than just-plain-X, would be (a) effective, and (b) harmless. > > It would break any call to *apply() that used X= to name the first > argument. There are currently 3020 such calls in the R code in CRAN.Okay. Scratch that idea.> One can avoid the problem by creating the function given as the FUN > argument when one calls lapply() and the like. Don't give that > function arguments named "X", "FUN", "USE.NAMES", etc. and perhaps > make use of R's lexical scoping to avoid having to use many arguments > to the function. E.g., instead of > sapply(1:5, sin) > use > sapply(1:5, function(theta) sin(theta)) > or instead of > myY <- 3 > sapply(1:5, atan2, y=myY) > use > myY <- 3 > sapply(1:5, function(x) atan2(myY, x))Again, all very sound advice but it does not address the problem of there being a trap for young players. The advice can only be applied by a user only if the user is *aware* of the trap. At this point it would appear that the problem is fundamentally unsolvable. :-( cheers, Rolf -- Technical Editor ANZJS Department of Statistics University of Auckland Phone: +64-9-373-7599 ext. 88276
Maybe Matching 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.