Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/71.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:对数百个变量进行剩余化的最快方法_R_Data.table_Regression_Lapply - Fatal编程技术网

R:对数百个变量进行剩余化的最快方法

R:对数百个变量进行剩余化的最快方法,r,data.table,regression,lapply,R,Data.table,Regression,Lapply,我有一个大的数据集,约30m个观测值,约800个变量,我需要对700个变量进行残差化,方法是将每个变量回归到3个变量上,然后存储残差。以下是我目前正在做的事情: io_d[, (vars_to_residualize_list) := lapply(.SD, function(X) {lm(X ~ X1 + X2 + X3)$residuals}), .SDcols = vars_to_residualize] 其中,vars_to_residualize是要

我有一个大的数据集,约30m个观测值,约800个变量,我需要对700个变量进行残差化,方法是将每个变量回归到3个变量上,然后存储残差。以下是我目前正在做的事情:

io_d[, (vars_to_residualize_list) := lapply(.SD, 
        function(X) {lm(X ~ X1 + X2 + X3)$residuals}),
        .SDcols = vars_to_residualize]
其中,vars_to_residualize是要残差化的变量列表,vars_to_residualize_列表是残差的新名称列表

这需要大约70个小时来完成所有变量


有没有更快的方法

也许这会显著地帮助您减少时间;稍微修改fLmSEXP的代码,以便能够提取残差

library(Rcpp)
library(RcppArmadillo)
library(rbenchmark)
## start from SEXP, most conversions, longest code
src <- '
Rcpp::List fLmSEXP(SEXP Xs, SEXP ys) {
Rcpp::NumericMatrix Xr(Xs);
Rcpp::NumericVector yr(ys);
int n = Xr.nrow(), k = Xr.ncol();
arma::mat X(Xr.begin(), n, k, false);
arma::colvec y(yr.begin(), yr.size(), false);
// fit model y ~ X, extract residuals
arma::colvec coef = arma::solve(X, y);
arma::colvec res  = y - X*coef;
// return the results
return Rcpp::List::create(Rcpp::Named("coefficients")=coef,Rcpp::Named("res")=res);
}
'
cppFunction(code=src, depends="RcppArmadillo")

我希望这会有帮助,或者至少给你一个方法。

X1、X2和X3都是连续的吗?稠密的您肯定应该在700个变量之间进行并行化。也可以向下跳过某个级别,直接使用lm.fit,而不是创建整个lm对象。阅读一下lm的源代码,了解一下这一点。它们都是因素。并行化是一个好主意。我将研究lm.fit。如果X1、X2和X3都是因子,你不是在3个变量上回归,而是在n1-1+n2-1+n3-1变量上回归,其中nk是Xk的水平数。好处是这种回归可能非常稀疏,您可以使用sparse.model.matrix&稀疏回归方法可能会快得多。如果你对矩阵代数/回归技术很小心,你甚至可能根本不需要计算设计矩阵。最后一件事——如果X1:X3在你的700个回归中总是相同的,你应该只使用model.matrix或sparse.model.matrix一次`来创建和存储你的设计矩阵。如果这个对象是重复的,不需要费心创建700次。看起来很有趣-我会尝试一下!
df <- data.frame(replicate(3,sample(1:4,300000,rep=TRUE)))
df = cbind(X = rnorm(300000),df)
head(df)
           X X1 X2 X3
1  0.6269854  1  4  3
2  0.4641201  1  1  4
3 -0.5625020  3  1  4
4  0.0452215  2  1  2
5  2.2453335  3  3  2
6  0.4045328  1  3  3
m <- as.matrix(cbind(X = df[,1],cbind(I = 1,df[,2:4])))
benchmark(
lm_res = lm(X ~ X1 + X2 + X3, data = df)$residuals,
flm_res = fLmSEXP(m[,2:5],m[,1])$res, replications = 100)[,1:4]

    test replications elapsed relative
2 flm_res          100    4.14    1.00
1  lm_res          100   12.46    3.01