Joris Meys
2014-Aug-25 14:27 UTC
[Rd] dubious behaviour of match.arg() with nested functions.
Dear all, I initially ran into this problem while rebuilding a package dependent on nleqslv. I got the following error: Error in match.arg(global) : 'arg' must be of length 1 This didn't occur in previous versions of nleqslv, but did in the current one (2.4). I think I pinned the problem down to the following example: Take two functions: test <- function(x=c("q","r","s"),global=c("d","e","r","z","q")){ x <- match.arg(x) global <- match.arg(global) return(list(x,global)) } test2 <- function(x=c("q","r","s"),global=c("d","z","q")){ test(x=x,global=global) } test2() calls an "internal" function test() that uses the same arguments. Note that for x both functions have exactly the same defaults, but not for global. Calling test2() gives the reported error:> test2()Error in match.arg(global) : 'arg' must be of length 1 I see the point of this error (global is not seen by test2() as default settings but as a character vector I presume), but I wonder why this isn't the case for x. Is this by design? If so, is there a part of the manual I overlooked? Cheers Joris -- Joris Meys Statistical consultant Ghent University Faculty of Bioscience Engineering Department of Mathematical Modelling, Statistics and Bio-Informatics tel : +32 9 264 59 87 Joris.Meys at Ugent.be ------------------------------- Disclaimer : http://helpdesk.ugent.be/e-maildisclaimer.php [[alternative HTML version deleted]]
Hadley Wickham
2014-Aug-25 15:22 UTC
[Rd] dubious behaviour of match.arg() with nested functions.
This is one of the perils of non-standard evaluation - functions are no longer referentially transparent. Hadley On Mon, Aug 25, 2014 at 9:27 AM, Joris Meys <jorismeys at gmail.com> wrote:> Dear all, > > I initially ran into this problem while rebuilding a package dependent on > nleqslv. I got the following error: > > Error in match.arg(global) : 'arg' must be of length 1 > > This didn't occur in previous versions of nleqslv, but did in the current > one (2.4). I think I pinned the problem down to the following example: > > Take two functions: > > test <- function(x=c("q","r","s"),global=c("d","e","r","z","q")){ > x <- match.arg(x) > global <- match.arg(global) > return(list(x,global)) > } > > test2 <- function(x=c("q","r","s"),global=c("d","z","q")){ > test(x=x,global=global) > } > > test2() calls an "internal" function test() that uses the same arguments. > Note that for x both functions have exactly the same defaults, but not for > global. > > Calling test2() gives the reported error: > >> test2() > Error in match.arg(global) : 'arg' must be of length 1 > > I see the point of this error (global is not seen by test2() as default > settings but as a character vector I presume), but I wonder why this isn't > the case for x. Is this by design? If so, is there a part of the manual I > overlooked? > > Cheers > Joris > > -- > Joris Meys > Statistical consultant > > Ghent University > Faculty of Bioscience Engineering > Department of Mathematical Modelling, Statistics and Bio-Informatics > > tel : +32 9 264 59 87 > Joris.Meys at Ugent.be > ------------------------------- > Disclaimer : http://helpdesk.ugent.be/e-maildisclaimer.php > > [[alternative HTML version deleted]] > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel-- http://had.co.nz/
peter dalgaard
2014-Aug-25 16:22 UTC
[Rd] dubious behaviour of match.arg() with nested functions.
On 25 Aug 2014, at 16:27 , Joris Meys <jorismeys at gmail.com> wrote:> Dear all, > > I initially ran into this problem while rebuilding a package dependent on > nleqslv. I got the following error: > > Error in match.arg(global) : 'arg' must be of length 1 > > This didn't occur in previous versions of nleqslv, but did in the current > one (2.4). I think I pinned the problem down to the following example: > > Take two functions: > > test <- function(x=c("q","r","s"),global=c("d","e","r","z","q")){ > x <- match.arg(x) > global <- match.arg(global) > return(list(x,global)) > } > > test2 <- function(x=c("q","r","s"),global=c("d","z","q")){ > test(x=x,global=global) > } > > test2() calls an "internal" function test() that uses the same arguments. > Note that for x both functions have exactly the same defaults, but not for > global. > > Calling test2() gives the reported error: > >> test2() > Error in match.arg(global) : 'arg' must be of length 1 > > I see the point of this error (global is not seen by test2() as default > settings but as a character vector I presume), but I wonder why this isn't > the case for x. Is this by design? If so, is there a part of the manual I > overlooked? >What you are experiencing would seem to amount to this:> f <- function(x=c("a","b","c")) {x <- letters[1:3] ; match.arg(x)} > f()[1] "a"> f <- function(x=c("a","b","c")) {x <- letters[1:2] ; match.arg(x)} > f()Error in match.arg(x) : 'arg' must be of length 1 Words to that effect appear in the Details section of ?match.arg -Peter D -- Peter Dalgaard, Professor, Center for Statistics, Copenhagen Business School Solbjerg Plads 3, 2000 Frederiksberg, Denmark Phone: (+45)38153501 Email: pd.mes at cbs.dk Priv: PDalgd at gmail.com
Berend Hasselman
2014-Aug-25 16:49 UTC
[Rd] dubious behaviour of match.arg() with nested functions.
On 25-08-2014, at 16:27, Joris Meys <jorismeys at gmail.com> wrote:> Dear all, > > I initially ran into this problem while rebuilding a package dependent on > nleqslv. I got the following error: > > Error in match.arg(global) : 'arg' must be of length 1 > > This didn't occur in previous versions of nleqslv, but did in the current > one (2.4). I think I pinned the problem down to the following example: > > Take two functions: > > test <- function(x=c("q","r","s"),global=c("d","e","r","z","q")){ > x <- match.arg(x) > global <- match.arg(global) > return(list(x,global)) > } > > test2 <- function(x=c("q","r","s"),global=c("d","z","q")){ > test(x=x,global=global) > } >Can?t the problem easily be avoided by using a slightly modified version of the test2() function? test2 <- function(x=c("q","r","s"),global=c("d","z","q")){ x <- match.arg(x) global <- match.arg(global) test(x=x,global=global) } Then test2() would be calling test() as it was intended to be called. I?ve tried that and it appears to solve the problem. So before calling nleqslv within another function use match.arg on those arguments with the same name and different defaults. And (possibly) document that some arguments expect a single value. Berend