10

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

这出现在问题的上下文中,并排打印矩阵和向量,但可能更普遍。

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

2 回答 2

13

使用sys.call

test_names <- function(...) {
  argnames <- sys.call()
  paste(lapply(argnames[-1], as.character), collapse = "")
}
#[1] "A * x - y = b"
于 2016-09-14T19:05:15.413 回答
7

正如电子邮件列表所描述的(此处),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])
}

它们相似,但帮助页面显示

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

所以这里有一个区别。

于 2016-09-14T19:24:41.753 回答