写作中的R功能,保持作用域记(Writing functions in R, keeping sco

2019-06-26 14:15发布

我经常写的是需要看到在我的环境中的其他对象的功能。 例如:

> a <- 3
> b <- 3
> x <- 1:5
> fn1 <- function(x,a,b) a+b+x
> fn2 <- function(x) a+b+x
> fn1(x,a,b)
[1]  7  8  9 10 11
> fn2(x)
[1]  7  8  9 10 11

正如预期的那样,这两个函数是相同的,因为fn2可以“看到” a和b在执行时。 但是,每当我开始利用这一优势,约30分钟后,我最终调用该函数没有必要的变量中的一个内(例如A或B)。 如果我不利用这一点,那么我觉得我身边掠过不必要的对象。

它更好更明确一些什么功能需要? 还是应该通过这个在线的评论或功能的其他文件被照顾的? 有没有更好的办法?

Answer 1:

如果我知道我会需要一些值参数化和重复调用的函数,我尽量避免使用封闭全局:

make.fn2 <- function(a, b) {
    fn2 <- function(x) {
        return( x + a + b )
    }
    return( fn2 )
}

a <- 2; b <- 3
fn2.1 <- make.fn2(a, b)
fn2.1(3)    # 8
fn2.1(4)    # 9

a <- 4
fn2.2 <- make.fn2(a, b)
fn2.2(3)    # 10
fn2.1(3)    # 8

这恰恰避免引用全局变量,而不是使用功能的封闭环境a和b。 的全局变量a和b的修改不会导致意想不到的副作用,当FN2实例调用。



Answer 2:

还有一个原因是,有些语言不允许全局变量:它们很容易导致断码。

R中的作用域规则允许你在一个懒惰的方式编写代码 - 让函数使用在其他环境变量可以为您节省一些打字,并在简单的情况下玩耍的伟大。

但是,如果将此做任何远程复杂,那么我建议你传递一个函数的所有变量,它需要(或者至少是,有一些深入的理智到位检查,在情况下,变量不存在回退) 。

在上面的例子:

最好的做法是使用FN1。

或者,你可以试试

 fn3 <- function(x)
   {
      if(!exists("a", envir=.GlobalEnv))
      {
         warning("Variable 'a' does not exist in the global environment")
         a <- 1
      }

      if(!exists("b", envir=.GlobalEnv))
      {
         warning("Variable 'b' does not exist in the global environment")
         b <- 2
      }

      x + a + b
   }


Answer 3:

问题是否到来,当你只是用一个全局变量的一个函数或当您尝试将变量分配? 如果是后者,我怀疑那是因为你不使用<<-作为函数内的分配。 虽然使用<<-似乎是黑暗的一面1它很可能满足您的需要。 如果是前者,该功能可能掩盖全局变量。

以这样的方式命名的全局变量,这将是难以掩盖他们在当地可能有帮助。 例如: global.pimultiples <- 1:4*pi



Answer 4:

全局变量的使用方法是在大多数语言一般气馁,和R也不例外。 经常短路功能使用短和一般变量名,这可能在全球环境中进行填充。 这是最安全的)包括在函数定义B中的所有变量) 分配默认值。 例如,写入F =函数(A,B),而F =函数(A = 0,B = NA)。



文章来源: Writing functions in R, keeping scoping in mind
标签: r scope