R中的循环和变量范围

时间:2013-06-15 16:41:19

标签: r variables for-loop functional-programming

我在R中有以下循环:

v = c(1,2,3,4)
s = create.some.complex.object()
for (i in v){
   print(i)
   s = some.complex.function.that.updates.s(s)
}
# s here has the right content.

毋庸置疑,这个循环在R中非常慢。 我尝试用函数式编写它:

   lapply(v, function(i){
      print(i)
      s = some.complex.function.that.updates.s(s)
   })
   # s wasn't updated.

但是这不起作用,因为s是按值传递的,而不是通过引用传递的。 我只需要最后一次迭代的结果,而不是所有的中间步骤。 如何以R风格制定第一个循环?

Mulone

3 个答案:

答案 0 :(得分:3)

   lapply(v, function(i){
      print(i)
      s = some.complex.function.that.updates.s(s)
      return(s)
   })

结果将是为s的每个值创建的对象v的列表。即使它应该已经传递了v的值,因为它是该函数执行的最后一个操作。

答案 1 :(得分:1)

如果您无法承受多次创建,那么就没有很多选择。如果没有看到您正在操作的对象,也很难说。如果对象正在增长/追加,您可以收集中间结果并在最后进行追加。如果它实际上是变异的,你应该尝试远离pass值并使用引用类(http://www.inside-r.org/r-doc/methods/ReferenceClasses)。然后修改它的函数实际上是一个你只需要调用n次的方法。

答案 2 :(得分:0)

循环本身真的是问题吗?或者更确切地说是执行some.complex.function.that.updates.s需要的时间? 一些R程序员会跳过箍来避免循环,但看看这个例子:

f <- function(a) a/1.001
loop <- function(n) { s = (1/f(1)^n); for (i in 1:n) s <- f(s); s}
system.time(loop(1E7))
   user  system elapsed 
  7.011   0.030   7.008

在循环中每次调用一个非常简单的函数时,这是0.7微秒(在MacBook Pro上)。