【问题标题】:R: get names of arguments passed in `...`R:获取传入`...`的参数名称
【发布时间】:2026-01-13 15:15:01
【问题描述】:

在使用... 提供参数列表的简单函数中,该函数是否有可能找到从调用环境传递的对象的名称 ?如果有,怎么做?

这出现在问题printing matrices and vectors side by side 的上下文中,但可能更笼统。

在这种情况下,参数... 也可以包含字符串,不需要名称。这是我的 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"  

【问题讨论】:

  • 你可以从 lapply 获得。它不保留列表名称。
  • 已编辑以显示所需的输出

标签: r parameter-passing expression-evaluation


【解决方案1】:

使用sys.call:

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

【讨论】:

    【解决方案2】:

    正如电子邮件列表所述(here),sys.call(如 Roland 所说)或 match.call 均可用于此目的。

    与 Roland 的解决方案相比,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])
    }
    

    它们很相似,但help page 说:

    sys.call() 类似于 [to match.call()],但不扩展 参数名称;

    所以这里有一个区别。

    【讨论】: