我有一个大数据集(约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个小时来浏览所有变量。
有更快的方法吗?
答案 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
我希望这会有所帮助,或者至少会给您一种方法。