如何获取R中的变量名称(替代)?

问题描述 投票:13回答:3

我试图通过几个函数传递变量,最后一个函数是我想要获得原始变量的名称。但是,似乎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参数是该函数的答案,因此,请您说明一下它的工作原理以及如何获得所需的信息。预先感谢!

r variables substitution
3个回答
15
投票

我建议您考虑将可选名称值传递给这些函数。我之所以这样说,是因为您似乎真的想将名称用作最终结果的标签;因此,变量本身与其名称并不重要。你可以做

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参数。


1
投票

一个hack,可能不是最好的方法:

fun2 <- function (var_pass) { fun1 (deparse(substitute(var_pass))) }

fun1 <- function (some_variable) {(some_variable))}

fun2(my_var)
# "my_var"

您可以对此运行get。但正如Paul H所建议的那样,有更好的方法来跟踪变量。


0
投票

我想建议的另一种方法是使用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)

[最重要的是,请注意fun1fun2都不会将变量名作为字符向量返回。返回的对象属于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
© www.soinside.com 2019 - 2024. All rights reserved.