deparse()和substitute()的包装

问题描述 投票:0回答:1

我正在尝试编写一个简单地围绕

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()
的组合,但不幸的是,这不起作用。

r rlang tidyeval
1个回答
0
投票

请记住,每个函数调用都会创建一个新框架来存储其变量。您的

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
的标签。

© www.soinside.com 2019 - 2024. All rights reserved.