我在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
答案 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上)。