Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
快速替代R car::预测子集平方和交叉积矩阵计算的方差分析_R_Performance_Matrix_Lm_Manova - Fatal编程技术网

快速替代R car::预测子集平方和交叉积矩阵计算的方差分析

快速替代R car::预测子集平方和交叉积矩阵计算的方差分析,r,performance,matrix,lm,manova,R,Performance,Matrix,Lm,Manova,我需要计算多元线性模型中的平方和叉积矩阵(实际上是这个矩阵的轨迹),Y(nxq)和x(nxp)。执行此操作的标准R代码为: require(MASS) require(car) # Example data q <- 10 n <- 1000 p <- 10 Y <- mvrnorm(n, mu = rep(0, q), Sigma = diag(q)) X <- as.data.frame(mvrnorm(n, mu = rnorm(p), Sigma =

我需要计算多元线性模型中的平方和叉积矩阵(实际上是这个矩阵的轨迹),Y(nxq)和x(nxp)。执行此操作的标准R代码为:

require(MASS)
require(car)

# Example data 
q <- 10
n  <- 1000
p <- 10
Y <- mvrnorm(n, mu = rep(0, q), Sigma = diag(q))
X <- as.data.frame(mvrnorm(n, mu = rnorm(p), Sigma = diag(p)))

# Fit lm
fit <- lm( Y ~ ., data = X )

# Type I sums of squares
summary(manova(fit))$SS    

# Type III sums of squares
type = 3 # could be also 2 (II)
car::Anova(fit, type = type)$SSP
car
对于大型n:

我已经尝试了
Rcpp
实现,取得了很大的成功,因为R中的这些矩阵产品已经使用了非常高效的代码

有没有关于如何更快地完成这项工作的提示

更新

在阅读了答案之后,我尝试了本文提出的解决方案,该解决方案依赖于QR/SVD/Cholesky分解来计算hat矩阵。然而,似乎
car::Anova
计算所有p=30矩阵的速度比我只计算一个(s=1)还要快!!例如,n=5000,q=10:

Unit: milliseconds
 expr       min        lq      mean    median        uq       max neval
   ME 1137.5692 1202.9888 1257.8979 1251.6834 1318.9282 1398.9343    10
   QR 1005.9082 1031.9911 1084.5594 1037.5659 1095.7449 1364.9508    10
  SVD 1026.8815 1065.4629 1152.6631 1087.9585 1241.4977 1446.8318    10
 Chol  969.9089 1056.3093 1115.9608 1102.1169 1210.7782 1267.1274    10
  CAR  205.1665  211.8523  218.6195  214.6761  222.0973  242.4617    10
更新2

目前最好的解决方案是检查
car::Anova
(即函数
car::Anova.III.mlm
,然后检查
car::linearHypothesis.mlm
)并重新实现它们,以考虑预测因子的子集,而不是所有预测因子

car
的相关代码如下(我跳过了检查,简化了一点):


B这一行和它下面的类似的
H1
行可能会得到改进:

H <- tcrossprod(tcrossprod(X, solve(crossprod(X))), X)

H这一行和它下面的类似的
H1
行可能会得到改进:

H <- tcrossprod(tcrossprod(X, solve(crossprod(X))), X)

H谢谢!我通过QR/SVD/Cholesky更新了问题,以包括结果,但是,car似乎仍然很快。您应该显示更多代码,因此我们有一个可复制的示例。我添加了一些示例数据,它可能只是多变量正常值。目前,我找到的最佳解决方案是通过我感兴趣的
car
重新实现代码,但只使用术语的子集。这是目前为止最快的。按照我在循环的最后一行中的答案中的建议,您可以获得另一个小的改进(大约7%)。我不确定这通常是正确的还是仅在示例中,但是
L%*%V%*%t(L)
是一个标量,因此您可以通过将最后一行替换为
crossprod(L%*%B)来获得另外7%/as.numeric(L%*%V%*%t(L))
。谢谢!我通过QR/SVD/Cholesky更新了问题,以包括结果,但是,car似乎仍然很快。您应该显示更多代码,因此我们有一个可复制的示例。我添加了一些示例数据,它可能只是多变量正常值。目前,我找到的最佳解决方案是通过我感兴趣的
car
重新实现代码,但只使用术语的子集。这是目前为止最快的。按照我在循环的最后一行中的答案中的建议,您可以获得另一个小的改进(大约7%)。我不确定这通常是正确的还是仅在示例中,但是
L%*%V%*%t(L)
是一个标量,因此您可以通过将最后一行替换为
crossprod(L%*%B)来获得另外7%/as.numeric(L%*%V%*%t(L))
H <- tcrossprod(tcrossprod(X, solve(crossprod(X))), X)