14

forパフォーマンスが向上しないため、ループを使用するのが R でのベスト プラクティスではないことはわかっています。ほとんどすべての場合、*apply私たちの問題を解決する家族の機能があります。

しかし、回避策が見当たらない状況に直面しています。

連続する値の変動率を計算する必要があります。

pv[1] <- 0
for(i in 2:length(x)) {
  pv[i] <- (x[i] - x[i-1])/x[i-1]
}

ご覧のとおり、x[i]要素と要素の両方を使用する必要がありx[i-1]ます。*apply関数を使用することで、x[i]. forループを回避できる方法はありますか?

4

3 に答える 3

20

次の方法でも同じ結果を得ることができます。

pv <- c(0)
y <- sapply(2:length(x), function(i) {pv <<- (x[i] - x[i-1])/x[i-1]})
c(0, y)

かつて問題だったforループの問題が最適化されました。多くの場合、forループは遅くはなく、適用ソリューションよりも速い場合があります。あなたはそれらの両方をテストして見る必要があります。私はあなたのforループが私の解決策よりも速いと確信しています。

編集:forループと適用ソリューション、およびDWinがベクトル化について説明していることを説明するために、Win7マシンでマイクロベンチマークを使用して4つのソリューションでベンチマークを実行しました。

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

ここに画像の説明を入力してください

于 2012-05-06T01:28:01.760 に答える
18

提供したのは小数の変動ですが、100を掛けると、「パーセントの変動」が得られます。

pv<- vector("numeric",length(x))
pv[1] <- 0
pv[-1] <- 100* ( x[-1] - x[-length(x)] )/ x[-length(x)]

ベクトル化されたソリューション。(そして、forループは* applyソリューションと同じくらい遅くなることに注意する必要があります...それほどきれいではありません。常にベクトル化されたアプローチを探してください。)

もう少し説明すると、はx[-length(x)]ベクトル、、、はベクトル、、であり、Rのベクトル演算は、明示的なループを使用していませんが、forループ本体と同じ演算を実行しています。Rは、最初にそれらのシフトされたベクトルの差を構築し、次に。で除算します。x[1:(length{x-1)]x[-1]x[2:length(x)]x[-length(x)] - x[-1]x[1:(length{x-1)]

于 2012-05-06T01:28:15.180 に答える
16

次のものも使用できますdiff

c( 0, diff(x) / x[-length(x)] )
c( 0, exp(diff(log(x))) - 1 )
于 2012-05-06T01:49:05.743 に答える