R: получить имена аргументов, переданных в `...`

В простой функции, используя ... чтобы предоставить список аргументов, возможно ли, чтобы эта функция находила имена объектов, переданных из вызывающей среды? Если так, то как?

Это возникает в контексте вопроса, печати матриц и векторов бок о бок, но, вероятно, является более общим.

В этом контексте аргументы ... также может включать строки символов, для которых не требуются имена. Вот мой MWE, где я пытался использовать deparse(substitute()), но безрезультатно.

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
}

Тестовое задание:

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]]"
> 

Мой желаемый результат для этого будет символьный вектор длины 7:

[1] "A"  " "   "x" " "  "y" " "   "b"

Здесь удивительно, что все результаты X[[i]]когда нет X упоминается везде

Следуя ответу @Roland, похоже, это делает то, что я хочу:

test_names2 <- function(...) {
  argnames <- sys.call()
  unlist(lapply(argnames[-1], as.character))
}

> test_names2(A, " * ", x, " - ", y, " = ", b)
[1] "A"   " * " "x"   " - " "y"   " = " "b"  

2 ответа

Использование sys.call:

test_names <- function(...) {
  argnames <- sys.call()
  paste(lapply(argnames[-1], as.character), collapse = "")
}
#[1] "A * x - y = b"

Как список рассылки описывает ( здесь) либо sys.call как сказал Роланд или match.call можно использовать для этого.

По сравнению с решением Роланда, решение с match.call похоже

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

Так что используйте его примерно так, потому что первый элемент - это имя самой функции.

f = function(...){
  return(as.list(match.call())[-1])
}

Они похожи, но на странице справки написано:

sys.call () похож на [match.call ()], но не расширяет имена аргументов;

Итак, вот одно отличие.

Другие вопросы по тегам