use*_*089 4 r parameter-passing expression-evaluation
在一个...用于提供参数列表的简单函数中,该函数是否可以找到从调用环境传递的对象的名称?如果是这样,怎么样?
这出现在问题的背景下,并排打印矩阵和向量,但可能更为一般.
在该上下文中,参数...还可以包括不需要名称的字符串.这是我的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
}
Run Code Online (Sandbox Code Playgroud)
测试:
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]]"
>
Run Code Online (Sandbox Code Playgroud)
我想要的输出是长度为7的字符向量:
[1] "A" " " "x" " " "y" " " "b"
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是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"
Run Code Online (Sandbox Code Playgroud)
用途sys.call:
test_names <- function(...) {
argnames <- sys.call()
paste(lapply(argnames[-1], as.character), collapse = "")
}
#[1] "A * x - y = b"
Run Code Online (Sandbox Code Playgroud)
正如电子邮件列表所描述的(此处)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
Run Code Online (Sandbox Code Playgroud)
所以有点像这样使用它,因为第一个元素是函数本身的名称。
f = function(...){
return(as.list(match.call())[-1])
}
Run Code Online (Sandbox Code Playgroud)
它们很相似,但帮助页面说:
sys.call() 类似于 [ to match.call() ],但不扩展参数名称;
所以这里有一个区别。