R:残留数百个变量的最快方法

时间:2018-10-11 16:23:58

标签: r data.table regression lapply

我有一个大数据集(约30m个观测值,约800个变量),我需要通过将每个变量回归到3个变量然后存储残差来残差700个变量。这是我目前正在做的事情:

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_list是残差的新名称的列表。

这大约需要70个小时来浏览所有变量。

有更快的方法吗?

1 个答案:

答案 0 :(得分:0)

也许这可以帮助您减少时间,明显fastLm() is much slower than lm();稍微修改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")

我创建数据框

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

我希望这会有所帮助,或者至少会给您一种方法。