我知道在R中使用for循环并不是最好的做法,因为它没有增强的性能.对于几乎所有情况,家庭都有*apply解决我们问题的功能.
但是我面临着一种我没有看到解决方法的情况.
我需要计算连续值的百分比变化:
pv[1] <- 0
for(i in 2:length(x)) {
pv[i] <- (x[i] - x[i-1])/x[i-1]
}
Run Code Online (Sandbox Code Playgroud)
所以,正如你所看到的,我必须既使用x[i]元素,也使用x[i-1]元素.通过使用这些*apply功能,我只看到如何使用x[i].无论如何,我可以避免for循环?
Tyl*_*ker 20
你可以得到相同的结果:
pv <- c(0)
y <- sapply(2:length(x), function(i) {pv <<- (x[i] - x[i-1])/x[i-1]})
c(0, y)
Run Code Online (Sandbox Code Playgroud)
曾经是问题的for循环问题已得到优化.for循环通常不会慢,甚至可能比应用解决方案更快.你必须测试它们并看到.我打赌你的for循环比我的解决方案更快.
编辑:只是为了说明for循环与应用解决方案以及DWin讨论的关于矢量化的内容,我在win 7机器上使用microbenchmark对四种解决方案进行了基准测试.
Unit: microseconds
expr min lq median uq max
1 DIFF_Vincent 22.396 25.195 27.061 29.860 2073.848
2 FOR.LOOP 132.037 137.168 139.968 144.634 56696.989
3 SAPPLY 146.033 152.099 155.365 162.363 2321.590
4 VECTORIZED_Dwin 18.196 20.063 21.463 23.328 536.075
Run Code Online (Sandbox Code Playgroud)

42-*_*42- 18
您提供的是分数变化,但如果乘以100,则得到"百分比变化":
pv<- vector("numeric",length(x))
pv[1] <- 0
pv[-1] <- 100* ( x[-1] - x[-length(x)] )/ x[-length(x)]
Run Code Online (Sandbox Code Playgroud)
矢量化的解决方案 (你应该注意,for循环和*apply解决方案一样慢......只是不那么漂亮.总是寻找一种矢量化的方法.)
为了解释一下:它x[-length(x)]是向量,x[1:(length{x-1)]并且x[-1]是向量,x[2:length(x)]并且R中的向量运算正在执行与for循环体相同的操作,尽管不使用显式循环.R首先构造那些移位向量的差异x[-length(x)] - x[-1],然后除以x[1:(length{x-1)].
Vin*_*ynd 16
您还可以使用diff:
c( 0, diff(x) / x[-length(x)] )
c( 0, exp(diff(log(x))) - 1 )
Run Code Online (Sandbox Code Playgroud)