Я довольно часто использую скользящую регрессию в R, и моя первоначальная установка выглядит примерно так:
dolm <- function(x) coef(lm(x[,1] ~ x[,2] + 0, data = as.data.frame(x)))
rollingCoef = rollapply(someData, 100, dolm)
Приведенный выше пример работает отлично, за исключением того, что он медленный, если у вас много итераций.
Чтобы ускорить это, я решил поэкспериментировать с Rcpp
пакет.
Сначала я подставил lm
с fastLm
, результат немного быстрее, но все еще медленно. Так что это подтолкнуло меня к попытке написать всю функцию коэффициентов скользящей регрессии в c ++, как для цикла, и затем интегрировать ее в R с помощью Rcpp.
Так что я изменил оригинальную функцию RcppArmadillo fastLm
к этому:
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::export]]
List rollCoef(const arma::mat& X, const arma::colvec& y, double window ) {
double cppWindow = window - 1;
double matRows = X.n_rows;
double matCols = X.n_cols - 1;
arma::mat coef( matRows - cppWindow, X.n_cols); // matrix for estimated coefficients
//for loop for rolling regression.
for( double i = 0 ; i < matRows - cppWindow ; i++ )
{
coef.row(i) = arma::trans(arma::solve(X( arma::span(i,i + cppWindow), arma::span(0,matCols)) , y.rows(i,i + cppWindow)));
}
return List::create(_["coefficients"] = coef);
}
и чем загрузить его в R с sourceCpp(file=".../rollCoef.cpp")
Так что это гораздо быстрее, чем rollapply
и он отлично работал на небольших примерах, но затем я применил его к ~ 200000 наблюдений за данными, которые он дал ~ половиной выходных данных в то же время rollapply
/fastLm
комбинация не дала ничего.
Так что здесь мне нужна помощь. Что не так с моей функцией? Почему в моей функции есть NA, а в NA нет rollapply
/fastLm
Однако, если я правильно понимаю, они оба основаны на arma::solve
? Любая помощь высоко ценится.
ОБНОВИТЬ
Вот воспроизводимый код:
require(Rcpp)
require(RcppArmadillo)
require(zoo)
require(repmis)
myData <- source_DropboxData(file = "example.csv",
key = "cbrmkkbssu5bn96", sep = ",", header = TRUE)
## in order to use my custom function "rollCoef" you should download it to R.
## The c++ code is presented above in the main question.
## Download it where you want as "rollCoef.cpp" and then download it to R with:
sourceCpp(file=".../rollCoeff.cpp"). # there should be your actual path.
myCoef = rollCoef(as.matrix(myData[,2]),myData[,1],260)
summary(unlist(myCoef)) # 80923 NA's
dolm = function(x) coef(fastLmPure(as.matrix(x[,2]), x[,1]))
myCoef2 = rollapply(myData, 260, dolm, by.column = FALSE)
summary(myCoef2) # 80923 NA's
dolm2 = function(x) coef(fastLm(x[,1] ~ x[,2] + 0, data = as.data.frame(x)))
myCoef3 = rollapply(myData, 260, dolm2, by.column = FALSE)
summary(myCoef3) # !!! No NA's !!!
head(unlist(myCoef)) ; head(unlist(myCoef2)) ; head(myCoef3)
Таким образом, вывод моей функции идентичен выводу RcppArmadillo fastLmPure
в сочетании с rollapply
и они оба производят АН, но rollapply
с fastLm
не. Как я понимаю например из ВОТ а также ВОТ fastLm
в основном призывает fastLmPure
, но почему в третьем методе нет NA, чем? Есть ли дополнительные возможности в fastLm
что мешает АН, что я не заметил?
Есть целый пакет RcppRoll сделать только этот пользовательский переход — и вы сможете расширить его и его rollit()
функция делать прокат lm()
также.
Других решений пока нет …