In a simple function using ...
to supply a list of arguments, is it possible for that function to find the names of the objects passed from the calling environment? If so, how?
This arises in the context of the question, printing matrices and vectors side by side, but is probably more general.
In that context, the arguments ...
can also include character strings, for which no names are required. Here is my MWE, where I tried using deparse(substitute())
, but to no avail.
test_names <- function(...) {
# get arguments
args <- list(...)
chars <- sapply(args, is.character)
names <- sapply(args, function(x) if(is.character(x)) " " else deparse(substitute(x)))
names
}
Test:
A = matrix(c(0.5, 1, 3, 0.75, 2.8, 4), nrow = 2)
x = c(0.5, 3.7, 2.3)
y = c(0.7, -1.2)
b = A %*% x - y
> test_names(A, " * ", x, " - ", y, " = ", b)
[1] "X[[i]]" " " "X[[i]]" " " "X[[i]]" " " "X[[i]]"
>
My desired output for this would be the character vector of length 7:
[1] "A" " " "x" " " "y" " " "b"
It is surprising here that the results are all X[[i]]
, when there is no X
mentioned anywhere.
Following @Roland's answer, this seems to do what I want:
test_names2 <- function(...) {
argnames <- sys.call()
unlist(lapply(argnames[-1], as.character))
}
> test_names2(A, " * ", x, " - ", y, " = ", b)
[1] "A" " * " "x" " - " "y" " = " "b"
As the email list describes (here) either sys.call
as Roland said or match.call
can be used for this.
In comparison to Roland's solution, a solution with match.call
looks like
f = function(...){
return(match.call())
}
d = f(x = 1, b = 5)
d
#f(x = 1, b = 5)
as.list(d[-1])
#$x
#[1] 1
#
#$b
#[1] 5
So use it somewhat like this, because the first element is the name of the function itself.
f = function(...){
return(as.list(match.call())[-1])
}
They are similar, but the help page says:
sys.call() is similar [to match.call()], but does not expand the argument names;
So here's one difference.
Use sys.call
:
test_names <- function(...) {
argnames <- sys.call()
paste(lapply(argnames[-1], as.character), collapse = "")
}
#[1] "A * x - y = b"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With