你的過程在我看來就像它需要循環,因爲每次迭代依賴於面前的一個。正如@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;
}
比較對速度的兩種方法。
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