首页 > 解决方案 > R:修改函数中定义的变量

问题描述

我有一长串变量,我正在使用一个函数将它们包装到一个列表中。然后将输出列表传递给另一个函数。

例如,

 #var1:var10
 foo <- function(){
 var1 = 1
 var2 = 3
 var3 = var1 + var3
 var4 = var3*var2 
 #e.t.c
 return(unlist(as.list(environment())))
 }
 params <- foo()
 foo_solve(model,params)

有没有办法访问 foo 中定义的变量并修改/覆盖默认值,然后foo重新评估并传递给foo_solve

我试过这种方法:

  foo <- function(..., args = list()) {  
  defaults <- list(a = -1,  c = -3, d = -4)  
  Args <- Reduce(modifyList, list(defaults, args, list(...)))
  return(unlist(Args))
   } 

但是基于其他变量计算的变量呢?

list(a = value, c = value2, d = a + d)不起作用。

提前致谢!

标签: rlistfunctionscope

解决方案


很抱歉,您已经正确地确定了使用函数来解决您的问题,但完全超出了范围。但是,让我们一个一个地回答问题:

有没有办法访问 foo 中定义的变量?

不,这是设计使函数中定义的内容保留在函数中,并且只能从函数及其子函数访问(即,无论函数本身正在调用什么)。

有没有办法...修改/覆盖默认值?

正如您正确推断的那样,这就是函数参数的用途。但解决方案更简单;首先,对于输入变量:

foo <- function(var1 = 1, var2 = 3) {
  var3 <- var1 + var2
  var4 <- var3 * var2
  return(c(var1, var2, var3, var4))
}

注意:您的 return 语句很难阅读,如果您需要第五个中间变量,则可能存在危险。它也会被返回,并且你不能保证返回变量的顺序。

如果您需要命名变量,请使用命名向量:

  return(c(v1=var1, s2=var2, var3=var3, m4=var4))

如果您的返回值比某些标量值更复杂,请使用list而不是简单的c.

但是基于其他变量计算的变量呢?

这就是有趣的地方;有几个选项取决于您想要做什么的复杂性以及用户应该拥有多少灵活性。首先,我们可以尝试扩展上述解决方案以包含计算值,并且仅在未给出时才计算它们:

foo <- function(var1 = 1, var2 = 3, var3, var4) {
  if (missing(var3))
    var3 <- var1 + var2
  if (missing(var4))
    var4 <- var3 * var2
  return(c(var1, var2, var3, var4))
}

该函数missing只是告诉您是否var3提供了参数。R 在这里有点有趣,因为在其他语言中,调用函数时必须给出没有默认值的函数参数。R 不会那样玩,只有在您要求时才需要该变量。

但是,如果var3var4是简单的计算,它们不能只在函数签名中定义吗?

  foo <- function(var1 = 1, var2 = 3, var3 = var1 + var2, var4 = var3 * var2) {
    return(c(var1, var2, var3, var4))
  }

事实证明它在这种情况下有效,但不要这样做!. 它不适用于更复杂的数据类型(列表、数据框),而且编码风格不好,因为它也使函数的可读性降低。


推荐阅读