R 为什么当我使用一个观察值运行回归时,`fastLm()`会返回结果?

R 为什么当我使用一个观察值运行回归时,`fastLm()`会返回结果?,r,rcpp,armadillo,R,Rcpp,Armadillo,为什么当我使用一个观察值运行回归时,fastLm()会返回结果 在下面的例子中,为什么lm()和fastLm()的结果不相等 library(Rcpp) library(RcppArmadillo) library(data.table) set.seed(1) DT <- data.table(y = rnorm(5), x1 = rnorm(5), x2 = rnorm(5), my.key = 1:5) # y x1 x2 my

为什么当我使用一个观察值运行回归时,
fastLm()
会返回结果

在下面的例子中,为什么
lm()
fastLm()
的结果不相等

library(Rcpp)
library(RcppArmadillo)
library(data.table)
set.seed(1)
DT <- data.table(y = rnorm(5), x1 = rnorm(5), x2 = rnorm(5), my.key = 1:5)
#             y         x1         x2 my.key
# 1: -0.6264538 -0.8204684  1.5117812      1
# 2:  0.1836433  0.4874291  0.3898432      2
# 3: -0.8356286  0.7383247 -0.6212406      3
# 4:  1.5952808  0.5757814 -2.2146999      4
# 5:  0.3295078 -0.3053884  1.1249309      5

lm(y ~ 1 + x1 + x2, data = DT[my.key == 1])
# Coefficients:
# (Intercept)           x1           x2  
#     -0.6265           NA           NA

fastLm(X = model.matrix(y ~ 1 + x1 + x2, data = DT[my.key == 1]), y = DT[my.key == 1]$y)
# Coefficients:
# (Intercept)          x1          x2 
#    -0.15825     0.12984    -0.23924 

model.matrix(y ~ 1 + x1 + x2, data = DT[my.key == 1])
#   (Intercept)        x1       x2
#             1 -0.8204684 1.511781
# attr(,"assign")
# [1] 0 1 2

DT[my.key == 1]$y
# [1] -0.6264538
从带有修改的RcppArmadillo的
库中,我也得到了相同的行为:

src <- '
Rcpp::List fLmTwoCastsOnlyCoefficients(Rcpp::NumericMatrix Xr, Rcpp::NumericVector yr) {
    int n = Xr.nrow(), k = Xr.ncol();
    arma::mat X(Xr.begin(), n, k, false);
    arma::colvec y(yr.begin(), yr.size(), false);
    arma::colvec coef = arma::solve(X, y);
    return Rcpp::List::create(Rcpp::Named("coefficients")=trans(coef));
}
'
cppFunction(code=src, depends="RcppArmadillo")

XX <- model.matrix(y ~ 1 + x1 + x2, data = DT[my.key == 1])
YY <- DT[my.key == 1]$y
fLmTwoCastsOnlyCoefficients(XX, YY)$coef
#            [,1]      [,2]       [,3]
# [1,] -0.1582493 0.1298386 -0.2392384

因为
fastLm
不担心排名不足;这是你为速度付出的部分代价

?fastLm


。。。Armadillo可以比stats包中的函数更快地执行类似lm.fit的操作,这是因为Armadillo使用QR分解的Lapack版本,而stats包使用修改的Linpack版本。因此Armadillo使用3级BLAS代码,而stats包使用1级BLAS。然而,Armadillo要么失败,要么更糟,在秩缺陷模型矩阵上产生完全错误的答案,而由于修改了Linpack代码,来自stats包的函数将正确处理它们

看看代码,代码的核心是

 arma::colvec coef = arma::solve(X, y);
这会进行QR分解。我们可以将
lmFast
结果与来自base R的
qr()
进行匹配(这里我不仅仅使用base R构造,而不是依赖
数据。表
):


因为
fastLm
不担心排名不足;这是你为速度付出的部分代价

?fastLm


。。。Armadillo可以比stats包中的函数更快地执行类似lm.fit的操作,这是因为Armadillo使用QR分解的Lapack版本,而stats包使用修改的Linpack版本。因此Armadillo使用3级BLAS代码,而stats包使用1级BLAS。然而,Armadillo要么失败,要么更糟,在秩缺陷模型矩阵上产生完全错误的答案,而由于修改了Linpack代码,来自stats包的函数将正确处理它们

看看代码,代码的核心是

 arma::colvec coef = arma::solve(X, y);
这会进行QR分解。我们可以将
lmFast
结果与来自base R的
qr()
进行匹配(这里我不仅仅使用base R构造,而不是依赖
数据。表
):


“然而,Armadillo将失败,或者更糟的是,在秩缺陷模型矩阵上产生完全错误的答案,而由于修改了Linpack代码,来自stats包的函数将正确处理它们。”“然而,Armadillo要么失败,要么更糟,在秩缺陷模型矩阵上产生完全错误的答案,而由于修改了Linpack代码,来自stats包的函数将正确处理它们。“希望这是唯一的原因,对吧?因此,如果我检查X'X的确定性,将阻止我考虑此类情况。即,
库(matrixcalc);是肯定的。(交叉PROD(XX))<代码>是代码> false <代码>,而<代码>是。肯定(交叉PROD(XX))< /代码>是代码>真< /代码>,在这种情况下,我不考虑第一种情况(XX只有一个观察,而XX只有5个)。我想不是,但我不知道。这是
arma::solve
的文档。。。FWIW RcppEigen包在其
fastLm()示例中有一组更完整的分解。但在这里,本雄辩地说:“这是你为速度付出的代价的一部分。”。我们给你足够的绳子吊死你自己。如果你想保护自己,请坚持使用
lm()
lm.fit()
,或者创建一个混合的“快速但安全”版本。希望这是唯一的原因,对吧?因此,如果我检查X'X的确定性,将阻止我考虑此类情况。即,
库(matrixcalc);是肯定的。(交叉PROD(XX))<代码>是代码> false <代码>,而<代码>是。肯定(交叉PROD(XX))< /代码>是代码>真< /代码>,在这种情况下,我不考虑第一种情况(XX只有一个观察,而XX只有5个)。我想不是,但我不知道。这是
arma::solve
的文档。。。FWIW RcppEigen包在其
fastLm()示例中有一组更完整的分解。但在这里,本雄辩地说:“这是你为速度付出的代价的一部分。”。我们给你足够的绳子吊死你自己。如果您想保护自己,请坚持使用
lm()
lm.fit()
,或创建一个混合的“快速但安全”版本。
 arma::colvec coef = arma::solve(X, y);
set.seed(1)
dd <- data.frame(y = rnorm(5), 
      x1 = rnorm(5), x2 = rnorm(5), my.key = 1:5)

X <- model.matrix(~1+x1+x2, data=subset(dd,my.key==1))
qr(X,dd$y)
## $qr
##   (Intercept)         x1       x2
## 1           1 -0.8204684 1.511781
library(Matrix)
rankMatrix(X) < ncol(X)  ## TRUE
X1 <- model.matrix(~1+x1+x2, data=dd)
rankMatrix(X1) < ncol(X1)  ## FALSE