【问题标题】:Static Variables in RR中的静态变量
【发布时间】:2010-11-08 11:41:07
【问题描述】:

我在 R 中有一个函数,我多次调用它。我想跟踪我调用它的次数,并用它来决定在函数内部做什么。这是我现在拥有的:

f = function( x ) {
   count <<- count + 1
   return( mean(x) )
}

count = 1
numbers = rnorm( n = 100, mean = 0, sd = 1 )
for ( x in seq(1,100) ) {
   mean = f( numbers )
   print( count )
}

我不喜欢我必须在函数范围之外声明变量计数。在 C 或 C++ 中,我可以只创建一个静态变量。我可以用 R 编程语言做类似的事情吗?

【问题讨论】:

    标签: r closures static-variables


    【解决方案1】:

    这是使用闭包(在编程语言意义上)的一种方法,即将计数变量存储在封闭环境中,只有您的函数可以访问:

    make.f <- function() {
        count <- 0
        f <- function(x) {
            count <<- count + 1
            return( list(mean=mean(x), count=count) )
        }
        return( f )
    }
    
    f1 <- make.f()
    result <- f1(1:10)
    print(result$count, result$mean)
    result <- f1(1:10)
    print(result$count, result$mean)
    
    f2 <- make.f()
    result <- f2(1:10)
    print(result$count, result$mean)
    result <- f2(1:10)
    print(result$count, result$mean)
    

    【讨论】:

    • 完美答案,这正是我想要的。 :)
    【解决方案2】:

    这是另一种方法。这个需要更少的打字并且(在我看来)更具可读性:

    f <- function(x) {
        y <- attr(f, "sum")
        if (is.null(y)) {
            y <- 0
        }
        y <- x + y
        attr(f, "sum") <<- y
        return(y)
    }
    

    这个sn-p,以及更复杂的概念示例可以通过in this R-Bloggers article找到

    【讨论】:

    • 这种方法的缺点是每次运行时实际上都是在创建 f 的副本。
    • 您能解释一下原因吗? @哈德利
    • @hshihab 由于 R 的“写入时复制”行为,更改 R 对象的属性(并且函数也是 R 对象)确实会创建一个副本。也许 data.table::setattr 函数会这是一件好事,因为它通过引用更新属性(不复制整个对象)......
    【解决方案3】:

    似乎 G. Grothendieck 在那里给出了正确的答案:Emulating static variable within R functions 但不知何故,这篇文章在谷歌搜索中获得了更有利的位置,所以我在这里复制这个答案:

    像这样在本地定义 f:

    f <- local({ 
      static <- 0
      function() { static <<- static + 1; static }
    })
    f()
    ## [1] 1
    f()
    ## [1] 2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-26
      • 1970-01-01
      • 1970-01-01
      • 2018-09-12
      • 2012-07-22
      • 2011-05-30
      • 1970-01-01
      • 2016-08-30
      相关资源
      最近更新 更多