Hi, In some cases the number of arguments passed as ... must be determined inside a function, without evaluating the arguments themselves. I use the following construct: dotlength <- function(...) length(substitute(expression(...))) - 1L # Usage (returns 3): dotlength(1, 4, something = undefined) How can I define a method for length() which could be called directly on `...`? Or is it an intention to extend the base length() function to accept ellipses? Regards, Denes
This question is better aimed at the r-help mailinglist as it is not about developing R itself. having said that, I can only gues why you want to do this, but why not do something like this: f <- function(...){ L <- list(...) len <- length() # you can stll pass the ... as follows: do.call(someotherfunction, L) } -Mark Op do 3 mei 2018 om 16:29 schreef D?nes T?th <toth.denes at kogentum.hu>:> Hi, > > > In some cases the number of arguments passed as ... must be determined > inside a function, without evaluating the arguments themselves. I use > the following construct: > > dotlength <- function(...) length(substitute(expression(...))) - 1L > > # Usage (returns 3): > dotlength(1, 4, something = undefined) > > How can I define a method for length() which could be called directly on > `...`? Or is it an intention to extend the base length() function to > accept ellipses? > > > Regards, > Denes > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >[[alternative HTML version deleted]]
As of 3.5.0 the ...length() function does exactly what you are asking for. Before that, I don't know of an easy way to get the length without evaluation via R code. There may be one I'm not thinking of though, I haven't needed to do this myself. Hope that helps. ~G On Thu, May 3, 2018 at 7:52 AM, Mark van der Loo <mark.vanderloo at gmail.com> wrote:> This question is better aimed at the r-help mailinglist as it is not about > developing R itself. > > > having said that, > > I can only gues why you want to do this, but why not do something like > this: > > > f <- function(...){ > L <- list(...) > len <- length() > # you can stll pass the ... as follows: > do.call(someotherfunction, L) > > } > > > -Mark > > Op do 3 mei 2018 om 16:29 schreef D?nes T?th <toth.denes at kogentum.hu>: > > > Hi, > > > > > > In some cases the number of arguments passed as ... must be determined > > inside a function, without evaluating the arguments themselves. I use > > the following construct: > > > > dotlength <- function(...) length(substitute(expression(...))) - 1L > > > > # Usage (returns 3): > > dotlength(1, 4, something = undefined) > > > > How can I define a method for length() which could be called directly on > > `...`? Or is it an intention to extend the base length() function to > > accept ellipses? > > > > > > Regards, > > Denes > > > > ______________________________________________ > > R-devel at r-project.org mailing list > > https://stat.ethz.ch/mailman/listinfo/r-devel > > > > [[alternative HTML version deleted]] > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >-- Gabriel Becker, Ph.D Scientist Bioinformatics and Computational Biology Genentech Research [[alternative HTML version deleted]]
In R-3.5.0 you can use ...length(): > f <- function(..., n) ...length() > f(stop("one"), stop("two"), stop("three"), n=7) [1] 3 Prior to that substitute() is the way to go > g <- function(..., n) length(substitute(...())) > g(stop("one"), stop("two"), stop("three"), n=7) [1] 3 R-3.5.0 also has the ...elt(n) function, which returns the evaluated n'th entry in ... , without evaluating the other ... entries. > fn <- function(..., n) ...elt(n) > fn(stop("one"), 3*5, stop("three"), n=2) [1] 15 Prior to 3.5.0, eval the appropriate component of the output of substitute() in the appropriate environment: > gn <- function(..., n) { + nthExpr <- substitute(...())[[n]] + eval(nthExpr, envir=parent.frame()) + } > gn(stop("one"), environment(), stop("two"), n=2) <environment: R_GlobalEnv> Bill Dunlap TIBCO Software wdunlap tibco.com On Thu, May 3, 2018 at 7:29 AM, D?nes T?th <toth.denes at kogentum.hu> wrote:> Hi, > > > In some cases the number of arguments passed as ... must be determined > inside a function, without evaluating the arguments themselves. I use the > following construct: > > dotlength <- function(...) length(substitute(expression(...))) - 1L > > # Usage (returns 3): > dotlength(1, 4, something = undefined) > > How can I define a method for length() which could be called directly on > `...`? Or is it an intention to extend the base length() function to accept > ellipses? > > > Regards, > Denes > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >[[alternative HTML version deleted]]
nargs() provides the number of arguments without evaluating them > f = function(x, ..., y) nargs() > f() [1] 0 > f(a=1, b=2) [1] 2 > f(1, a=1, b=2) [1] 3 > f(x=1, a=1, b=2) [1] 3 > f(stop()) [1] 1 On 05/03/2018 11:01 AM, William Dunlap via R-devel wrote:> In R-3.5.0 you can use ...length(): > > f <- function(..., n) ...length() > > f(stop("one"), stop("two"), stop("three"), n=7) > [1] 3 > > Prior to that substitute() is the way to go > > g <- function(..., n) length(substitute(...())) > > g(stop("one"), stop("two"), stop("three"), n=7) > [1] 3 > > R-3.5.0 also has the ...elt(n) function, which returns > the evaluated n'th entry in ... , without evaluating the > other ... entries. > > fn <- function(..., n) ...elt(n) > > fn(stop("one"), 3*5, stop("three"), n=2) > [1] 15 > > Prior to 3.5.0, eval the appropriate component of the output > of substitute() in the appropriate environment: > > gn <- function(..., n) { > + nthExpr <- substitute(...())[[n]] > + eval(nthExpr, envir=parent.frame()) > + } > > gn(stop("one"), environment(), stop("two"), n=2) > <environment: R_GlobalEnv> > > > > > Bill Dunlap > TIBCO Software > wdunlap tibco.com > > On Thu, May 3, 2018 at 7:29 AM, D?nes T?th <toth.denes at kogentum.hu> wrote: > >> Hi, >> >> >> In some cases the number of arguments passed as ... must be determined >> inside a function, without evaluating the arguments themselves. I use the >> following construct: >> >> dotlength <- function(...) length(substitute(expression(...))) - 1L >> >> # Usage (returns 3): >> dotlength(1, 4, something = undefined) >> >> How can I define a method for length() which could be called directly on >> `...`? Or is it an intention to extend the base length() function to accept >> ellipses? >> >> >> Regards, >> Denes >> >> ______________________________________________ >> R-devel at r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel >> > > [[alternative HTML version deleted]] > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >This email message may contain legally privileged and/or...{{dropped:2}}
Thank you Bill (and the R-Core Team), this is even more than what I thought of. I somehow missed this in the NEWS. BTW, substitue(...()) is beautiful. On 05/03/2018 05:01 PM, William Dunlap wrote:> In R-3.5.0 you can use ...length(): > > f <- function(..., n) ...length() > > f(stop("one"), stop("two"), stop("three"), n=7) > [1] 3 > > Prior to that substitute() is the way to go > > g <- function(..., n) length(substitute(...())) > > g(stop("one"), stop("two"), stop("three"), n=7) > [1] 3 > > R-3.5.0 also has the ...elt(n) function, which returns > the evaluated n'th entry in ... , without evaluating the > other ... entries. > > fn <- function(..., n) ...elt(n) > > fn(stop("one"), 3*5, stop("three"), n=2) > [1] 15 > > Prior to 3.5.0, eval the appropriate component of the output > of substitute() in the appropriate environment: > > gn <- function(..., n) { > + nthExpr <- substitute(...())[[n]] > + eval(nthExpr, envir=parent.frame()) > + } > > gn(stop("one"), environment(), stop("two"), n=2) > <environment: R_GlobalEnv> > > > > > Bill Dunlap > TIBCO Software > wdunlap tibco.com <http://tibco.com> > > On Thu, May 3, 2018 at 7:29 AM, D?nes T?th <toth.denes at kogentum.hu > <mailto:toth.denes at kogentum.hu>> wrote: > > Hi, > > > In some cases the number of arguments passed as ... must be > determined inside a function, without evaluating the arguments > themselves. I use the following construct: > > dotlength <- function(...) length(substitute(expression(...))) - 1L > > # Usage (returns 3): > dotlength(1, 4, something = undefined) > > How can I define a method for length() which could be called > directly on `...`? Or is it an intention to extend the base length() > function to accept ellipses? > > > Regards, > Denes > > ______________________________________________ > R-devel at r-project.org <mailto:R-devel at r-project.org> mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > <https://stat.ethz.ch/mailman/listinfo/r-devel> > >-- Dr. T?th D?nes ?gyvezet? Kogentum Kft. Tel.: 06-30-2583723 Web: www.kogentum.hu
On 03/05/2018 11:01 AM, William Dunlap via R-devel wrote:> In R-3.5.0 you can use ...length(): > > f <- function(..., n) ...length() > > f(stop("one"), stop("two"), stop("three"), n=7) > [1] 3 > > Prior to that substitute() is the way to go > > g <- function(..., n) length(substitute(...())) > > g(stop("one"), stop("two"), stop("three"), n=7) > [1] 3 > > R-3.5.0 also has the ...elt(n) function, which returns > the evaluated n'th entry in ... , without evaluating the > other ... entries. > > fn <- function(..., n) ...elt(n) > > fn(stop("one"), 3*5, stop("three"), n=2) > [1] 15 > > Prior to 3.5.0, eval the appropriate component of the output > of substitute() in the appropriate environment: > > gn <- function(..., n) { > + nthExpr <- substitute(...())[[n]] > + eval(nthExpr, envir=parent.frame()) > + } > > gn(stop("one"), environment(), stop("two"), n=2) > <environment: R_GlobalEnv> >Bill, the last of these doesn't quite work, because ... can be passed down through a string of callers. You don't necessarily want to evaluate it in the parent.frame(). For example: x <- "global" f <- function(...) { x <- "f" g(...) } g <- function(...) { firstExpr <- substitute(...())[[1]] c(list(...)[[1]], eval(firstExpr, envir = parent.frame())) } Calling g(x) correctly prints "global" twice, but calling f(x) incorrectly prints [1] "global" "f" You can get the first element of ... without evaluating the rest using ..1, but I don't know a way to do this for general n in pre-3.5.0 base R. Duncan Murdoch
> On 3 May 2018, at 16:52 , Mark van der Loo <mark.vanderloo at gmail.com> wrote: > > This question is better aimed at the r-help mailinglist as it is not about > developing R itself.Um, no... People there might well send you back here. As for the original question, there are also variations over dddlen <- function(...)length(match.call(expand.dots=FALSE)$...) -- Peter Dalgaard, Professor, Center for Statistics, Copenhagen Business School Solbjerg Plads 3, 2000 Frederiksberg, Denmark Phone: (+45)38153501 Office: A 4.23 Email: pd.mes at cbs.dk Priv: PDalgd at gmail.com