我正在尝试编写一个简单地围绕
deparse()
和 substitute()
的函数,如下所示:
get_name <- function(x) {
deparse(substitute(x))
}
get_name()
的要点是返回函数参数的字符对象。在我的全局环境中调用时,get_name()
正在工作,如下所示:
# no problem here, returns "Variable1" as expected
get_name(x = Variable1)
[1] "Variable1"
问题是当我尝试在另一个函数中使用
get_name()
时。就像下面这个:
# a new function that uses get_name()
new_function <- function(arg1) {
get_name(x = arg1)
}
# returns "arg1"
# should be returning "Variable1"
new_function(arg1 = Variable1)
[1] "arg1"
我最初的想法是必须有办法解决这个使用环境。但是,当尝试使用
eval()
时,它不起作用,因为 Variable1
实际上并不是我的全局环境中的对象,它只是我的函数参数中的值。
我还尝试了其他
rlang
功能,例如 as_string()
和 ensym()
的组合,但不幸的是,这不起作用。
请记住,每个函数调用都会创建一个新框架来存储其变量。您的
get_name
函数具有与 new_function
不同的框架。您希望替换发生在 new_function
的框架中,并且当您调用它时 substitute
引用它的第一个参数。
这是一个我认为可以满足您需求的函数:
get_name <- function(x) {
nm <- substitute(x)
pf <- parent.frame()
deparse(do.call(substitute, list(nm,pf)))
}
我们首先使用
substitute
获取您想要名称的参数(示例中的 arg1)并将其存储在 nm
中。 我们不需要 deparse,因为我们想要一个语言对象。
然后我们使用
parent.frame
来抓取调用这个函数的框架。
然后使用
do.call
使用我们已经获取的名称和父框架构造对 substitute
的调用,然后解析该结果。
以你的例子
new_function
:
> get_name <- function(x) {
+ nm <- substitute(x)
+ pf <- parent.frame()
+ deparse(do.call(substitute, list(nm,pf)))
+ }
> new_function <- function(arg1) {
+ get_name(x = arg1)
+ }
> new_function(arg1 = Variable1)
[1] "Variable1"
> new_function(arg1 = something_else)
[1] "something_else"
那么你也可以做这样的事情:
myplot <- function(x, y) {
xl <- get_name(x)
yl <- get_name(y)
plot(x, y,
xlab=paste('x:', xl),
ylab=paste('y:', yl))
}
myplot(runif(100), rnorm(100))
该图具有基于
get_name
的标签。