如何在一个函数中创建一个变量,该函数的名称取自R中的参数?

时间:2016-05-19 10:43:18

标签: r

我对R来说是一个完全的初学者,并且一直在努力解决我的问题,因为尽管我确定这是一个非常基本的问题,但我发现很难解释我想要什么。做。我很欣赏stackoverflow只适用于严肃的程序员,所以如果有人甚至可以指向别人的问题处理相同的主题,我会非常感激。话虽如此:

我想要做的是有一个函数能够读取并分配向量的名称,而不仅仅是其内容。我写的时候:

num <- 5
func <- function(x) {
    x <<- 8
}
func(num)

我认为它会创建一个名为&#34; num&#34;的新矢量。 - 就像在,它会像:

func(num) 
num <<- 8. 

但它要么只创建一个字面上称为&#34; x&#34;的新矢量,并指定&#34; 8&#34;对它,或它试图分配&#34; 8&#34;对于&#34; 5&#34;,我无法确定哪个。无论哪种方式,我怎么能告诉R我希望它利用我在论证中写的内容作为矢量名?

2 个答案:

答案 0 :(得分:3)

您可以使用函数的return语句:

num = 5
func = function(x) {
    return(x)
}
num = func(8)
num
# [1] 8

另见this tutorial I wrote,这提供了一些关于功能,范围等方面的更深入的信息。

另请注意,通常不需要<<-运算符,因为这会导致难以理解的代码。请参阅示例this SO post

答案 1 :(得分:1)

在我提供解决方案之前,我认为最好解决关于论证传递的错误观念。当您将函数调用为

func(num)

您没有将变量的名称作为参数值传递,而是将变量的作为参数值传递。换句话说,如果num等于5,那么您传递数字5.如果函数使用标准参数求值,那么它将不知道参数中使用的变量名称,甚至如果有一个变量名(如果参数值是从文字或表达式产生的话,可能没有)。

如果要将变量名称作为参数值传递,则需要引用它:

func('num')

话虽如此,有一种称为非标准的论证评估。 R是相当不寻常的,因为它提供了一种机制来检索绑定到参数的参数表达式,这实际上可以允许您从函数内部检索变量名称。 substitute()函数通常用于此目的。用作参数表达式的变量名称甚至不必与现有变量相对应。

f <- function(x) as.character(substitute(x));
f(some.var);
## [1] "some.var"

许多基本R函数使用非标准参数评估,例如rm()library()

有几种方法可以做你想做的事。

1: assign()

assign()函数可用于在任何环境中分配参数化变量名称。您的分配目标似乎是全局环境,有时称为工作区环境,可以使用globalenv()(或.GlobalEnv)访问。

f <- function(x) assign(x,8,envir=globalenv());
num;
## Error: object 'num' not found
f('num');
num;
## [1] 8

2:环境访问

可以取消引用环境对象并直接分配它,虽然奇怪的是,看起来返回环境对象的函数调用或表达式不能以这种方式用作左值。换句话说,您需要先捕获变量中的环境对象,然后才能取消引用并分配它。

f <- function(x) { e <- globalenv(); e[[x]] <- 9; };
num;
## Error: object 'num' not found
f('num');
num;
## [1] 9
globalenv()$num <- 'why doesn\'t this work???';
## Error in globalenv()$num <- "why doesn't this work???" :
##   invalid (NULL) left side of assignment

3: parse()eval()<<-

我们可以使用superassignment运算符通过动态评估来分配动态名称。

f <- function(x) eval(parse(text=paste0(x,' <<- 10;')));
num;
## Error: object 'num' not found
f('num');
num;
## [1] 10

上述任何方法都可以与非标准参数评估相结合,例如:

f <- function(x) assign(as.character(substitute(x)),11,envir=globalenv());
num;
## Error: object 'num' not found
f(num);
num;
## [1] 11