为什么RcppArmadillo的fastLmPure在输出中产生NA,而fastLm没有?

Why RcppArmadillo's fastLmPure produces NA's in output but fastLm doesn't?

本文关键字:NA fastLm 没有 RcppArmadillo fastLmPure 输出 为什么      更新时间:2023-10-16

我经常在R中使用滚动回归,我的初始设置类似于:

dolm <- function(x) coef(lm(x[,1] ~ x[,2] + 0, data = as.data.frame(x)))
rollingCoef = rollapply(someData, 100, dolm)

上面的例子工作得很好,但若你们有很多迭代,它会很慢。

为了加快速度,我决定试用Rcpp软件包。

首先,我用fastLm代替了lm,结果有点快,但仍然很慢。因此,这促使我尝试用c++将整个滚动回归的系数函数写成循环,然后在Rcpp的帮助下将其积分到R中。

所以我把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);
}

然后用sourceCpp(file=".../rollCoef.cpp") 将其下载到R

因此,它比rollapply快得多,在小例子中效果很好,但与我将其应用于约200000次数据观测相比,它产生了约一半的NA输出,同时rollapply/fastLm组合没有产生任何NA。

所以在这里我需要一些帮助。我的功能出了什么问题?为什么我的函数输出中有NA,而rollapply/fastLm中没有NA,但是,如果我理解正确的话,它们都是基于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)

因此,我的函数的输出与RcpArmadillo的fastLmPurerollapply的输出相同,它们都产生NA,而rollapplyfastLm不产生NA。据我所知,例如,从HERE和HERE,fastLm基本上是在调用fastLmPure,但为什么第三个方法中没有NA?fastLm中是否有一些额外的功能可以防止我没有发现的NA?

有一个完整的包RcppRoll来执行自定义滚动,您应该能够扩展它及其rollit()函数来执行lm()滚动。