各反復は、その前に1に依存しているため、それは、ループを必要とするようにあなたのプロセスは、私には見えます。 @ Gregor de Cilliaがコメントに言及しているように、あなたはC++でスピードの向上を図ることができます。
まず、データを設定します。
set.seed(1)
e <- matrix(data = rnorm(n = 46000, mean = 1000, sd = 200),
nrow = 46,
ncol = 1000)
m <- matrix(data = rnorm(n = 46000, mean = 2000, sd = 200),
nrow = 46,
ncol = 1000)
r <- matrix(data = rnorm(n = 46000, mean = 4, sd = 0.5),
nrow = 46,
ncol = 1000)
x <- matrix(data = NA_real_, nrow = 45, ncol = 1000)
y <- matrix(data = NA_real_, nrow = 46, ncol = 1000)
y[1,] <- rnorm(n = 1000, 10000, 1000)
Rcpp
ファイルでC++関数を定義します。これは二つの行列x
とリスト項目としてy
でリストを返します:
List pension(NumericMatrix e,
NumericMatrix m,
NumericMatrix r,
NumericVector yfirstrow) {
int ncols = e.cols();
int nrows = e.rows();
NumericMatrix x(nrows - 1, ncols);
NumericMatrix y(nrows, ncols);
y(0, _) = yfirstrow;
for(int i = 1; i < nrows; i++) {
x(i-1, _) = (y(i-1, _) + m(i-1, _) * 6 - 0.5 * e(i-1, _)) * r(i-1, _);
y(i, _) = y(i-1, _) + x(i-1, _) - e(i-1, _) + m(i-1, _)* 12;
};
List ret;
ret["x"] = x;
ret["y"] = y;
return ret;
}
はスピードの2つの方法を比較してください。
microbenchmark::microbenchmark(
R = {
for (i in 2:46) {
x[i-1,] <- unlist((y[i-1,] + m[i-1,]*6 - 0.5*e[i-1,]) * r[i-1,])
y[i,]<- unlist(y[i-1,]+x[i-1,]-e[i-1,]+m[i-1,]*12)
}
},
cpp = {
cppList <- pension(e, m, r, y[1,])
},
times = 100
)
必ず出力が一致を行います。
> identical(x, cppList$x)
[1] TRUE
> identical(y, cppList$y)
[1] TRUE
スピードテストの結果:
Unit: microseconds
expr min lq mean median uq max neval
R 3309.962 3986.569 6961.838 5244.479 6219.215 96576.592 100
cpp 879.713 992.229 1266.014 1124.345 1273.691 3041.966 100
のでRcpp
ソリューションはより速く、ここで5倍程度であるが、正直に言うと、R
ループあなたが作ったデータセットに対してあまり目立たないことはありません(反復回数が45回で、Rループのオーバーヘッドはあまり大きな障害ではありません)。本当にスピードが必要な場合は、C++が役に立ちます。
'RCpp'パッケージを使用して、' C++ 'で計算を書くことができます。このようにすれば、優れたパフォーマンスが保証され、コードの移行が非常に簡単になります。 –
これをチェックしてください:https://stackoverflow.com/questions/2908822/speed-up-the-loop-operation-in-r/8474941#8474941質問と回答の両方がとても良いです。 – p0bs