Interception and use of the value of an additional variable captured at points (...)

I need to intercept the value of the optional xlim

in a function so that I can change its units before plotting. The following function confirms what has been posted xlim

, but I cannot access the value.

foo <- function(x, y, ...) {
    if ("xlim" %in% names(list(...))) {
        print(xlim) # not found/can't use value!
        }
    # modify xlim and pass to plotting functions
    return()
    }

      

But foo(x = 1:5, y = 1:5, xlim = c(2,4))

it gives:

Error in print(xlim) : object 'xlim' not found

      

What trick do I need to use value? It looks like it should just work, but I see myself looking back at SO that the points can be annoying. I've played around a bit with exists

, deparse

etc., but I'm really not using these functions "correctly".

EDIT: here is the last snippet which was the fastest way to access the value:

dots <- list(...)
if (any(names(dots) == "xlim")) {
    xlim <- dots$xlim
    print(xlim)
    }

      

+3


source to share


1 answer


This is because it is xlim

actually a list item and is not (yet) an actual object in the function environment. You could do

foo <- function(x, y, ...) {
    m <- match.call(expand.dots = FALSE)$...
    if(any(names(m) == "xlim")) m[["xlim"]]
    else stop("no xlim value")
}
foo(x = 1:5, y = 1:5, xlim = c(2,4))
# c(2, 4)
foo(x = 1:5, y = 1:5, ylim = c(2,4))
# Error in foo(x = 1:5, y = 1:5, ylim = c(2, 4)) : no xlim value

      

You can see what it does match.call

if we consider the function as

f <- function(x, y, ...) {
    match.call(expand.dots = FALSE)$...
}

      

This is a list of all the dot arguments entered with their corresponding expressions, so there are many different ways to get the values, above all this is one way.



f(x = 1:5, y = 1:5, xlim = c(2,4))
# $xlim
# c(2, 4)

      

Alternatively, you can do

g <- function(x, y, ...) {
    dots <- list(...)
    any(names(dots) == "xlim")
}
g(x = 1:5, y = 1:5, xlim = c(2,4))
# [1] TRUE

      

Also keep in mind that it match.call

stores the argument as non-evaluating call

while list(...)

evaluating the argument. This can be important for passing arguments to other functions.

+2


source







All Articles