Pass optional arguments to function, three dots
Asked Answered
S

3

7

I'm confused how ... works.

tt = function(...) {
  return(x)
}

Why doesn't tt(x = 2) return 2?

Instead it fails with the error:

Error in tt(x = 2) : object 'x' not found

Even though I'm passing x as argument ?

Sanies answered 24/5, 2018 at 13:52 Comment(3)
you are not passing x as argument.Pilfer
tt = function(x,levels) { if(missing(levels)) return(x) } tt(x = 2)Cleave
Related post: #5891076Gabriella
H
12

Because everything you pass in the ... stays in the .... Variables you pass that aren't explicitly captured by a parameter are not expanded into the local environment. The ... should be used for values your current function doesn't need to interact with at all, but some later function does need to use do they can be easily passed along inside the .... It's meant for a scenario like

ss <- function(x) {
   x
}

tt <- function(...) {
  return(ss(...))
}

tt(x=2)

If your function needs the variable x to be defined, it should be a parameter

tt <- function(x, ...) {
  return(x)
}

If you really want to expand the dots into the current environment (and I strongly suggest that you do not), you can do something like

tt <- function(...) {
  list2env(list(...), environment())
  return(x)
}
Hux answered 24/5, 2018 at 13:59 Comment(0)
P
3

if you define three dots as an argument for your function and want it to work, you need to tell your function where the dots actually go. in your example you are neither defining x as an argument, neither ... feature elsewhere in the body of your function. an example that actually works is:

tt <- function(x, ...){
       mean(x, ...)
}

x <- c(1, 2, 3, NA)
tt(x)
#[1] NA
tt(x, na.rm = TRUE)
#[1] 2

here ... is referring to any other arguments that the function mean might take. additionally you have a regular argument x. in the first example tt(x) just returns mean(x), whilst in the second example tt(x, na.rm = TRUE), passes the second argument na.rm = TRUE to mean so tt returns mean(x, na.rm = TRUE).

Pilfer answered 24/5, 2018 at 14:3 Comment(0)
B
2

Another way that the programmers of R use a lot is list(...) as in

tt <- function(...) {
    args <- list(...)    # As in this
    if("x" %in% names(args))
        return(args$x)
    else
        return("Something else.")
}

tt(x = 2)
#[1] 2

tt(y = 1, 2)
#[1] "Something else."

I believe that this is one of their favorite, if not the favorite, way of handling the dots arguments.

Boxcar answered 24/5, 2018 at 14:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.