【问题标题】:R: modify variables defined in functionR:修改函数中定义的变量
【发布时间】:2019-07-24 04:06:41
【问题描述】:

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

例如,

 #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) 不起作用。

提前致谢!

【问题讨论】:

    标签: r list function scope


    【解决方案1】:

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

    有没有办法访问 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))
      }
    

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

    【讨论】:

      猜你喜欢
      • 2012-01-15
      • 2015-11-11
      • 1970-01-01
      • 1970-01-01
      • 2018-02-22
      • 2021-12-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多