我试图通过几个函数传递变量,最后一个函数是我想要获得原始变量的名称。但是,似乎R中的替代功能仅在“本地”环境中或仅在一个级别上使用。好吧,让我用代码解释一下:
fun1 <- function (some_variable) {deparse(substitute(some_variable)}
fun2 <- function (var_pass) { fun1 (var_pass) }
my_var <- c(1,2) # I want to get 'my_var' in the end
fun2 (my_var) # > "var_pass"
好吧,好像我们在打印仅传递给fun1的变量的名称。替代品的文档告诉我们,我们可以使用env参数来指定外观。但是通过传递。Global或。BaseNamespaceEnv作为替代参数,我得到了更奇怪的结果-“ some_variable”
我相信使用env参数是该函数的答案,因此,请您说明一下它的工作原理以及如何获得所需的信息。预先感谢!
我建议您考虑将可选名称值传递给这些函数。我之所以这样说,是因为您似乎真的想将名称用作最终结果的标签;因此,变量本身与其名称并不重要。你可以做
fun1 <- function (some_variable, name=deparse(substitute(some_variable))) {
name
}
fun2 <- function (var_pass, name=deparse(substitute(var_pass))) {
fun1 (var_pass, name)
}
my_var <- c(1,2)
fun2(my_var)
# [1] "my_var"
fun1(my_var)
# [1] "my_var"
这样,如果您最终拥有一些奇数变量名称以及为结果赋予更好名称的名称,则至少可以选择。并且默认情况下,它应该执行您想要的操作而不必使用name参数。
一个hack,可能不是最好的方法:
fun2 <- function (var_pass) { fun1 (deparse(substitute(var_pass))) }
fun1 <- function (some_variable) {(some_variable))}
fun2(my_var)
# "my_var"
您可以对此运行get
。但正如Paul H所建议的那样,有更好的方法来跟踪变量。
我想建议的另一种方法是使用rlang::enexpr
。主要优点是我们不需要在参数中携带原始变量名。缺点是我们必须处理使用起来有点棘手的表达式。
> fun1 <- function (some_variable) {
... message("Entering fun1")
... rlang::enexpr(some_variable)
... }
> fun2 <- function (var_pass) {
... message("Entering fun2")
... eval(parse(text=paste0("fun1(", rlang::enexpr(var_pass), ")")))
... }
> my_var <- c(1, 2)
> fun1(my_var)
Entering fun1
my_var
> fun2(my_var)
Entering fun2
Entering fun1
my_var
这里的诀窍是我们必须评估fun2
中的参数名称,并将对fun1
的调用构建为character
。如果只用fun1
调用enexpr(var_pass)
,我们将失去fun2
变量名的概念,因为enexpr(var_pass)
永远不会在fun2
中求值:
> bad_fun2 <- function (var_pass) {
... message("Entering bad fun2")
... fun1(rlang::enexpr(var_pass))
... }
> bad_fun2(my_var)
Entering bad fun2
Entering fun1
rlang::enexpr(var_pass)
[最重要的是,请注意fun1
和fun2
都不会将变量名作为字符向量返回。返回的对象属于name
类(当然可以强制为character
)。好的一面是您可以直接在其上使用eval
。
> ret <- fun2(my_var)
Entering fun2
Entering fun1
> as.character(ret)
[1] "my_var"
> class(ret)
[1] "name"
> eval(ret)
[1] 1 2