使用ForEach单步遍历1000';回归方程

使用ForEach单步遍历1000';回归方程,r,foreach,parallel-processing,doparallel,R,Foreach,Parallel Processing,Doparallel,首先是一些数据。为协变量和我感兴趣的回归结果创建一个数据框架,为解释变量创建一个数据框架 我正在做的是逐步通过lm(结果~mycovs+beta的第I列),在本例中,收集残差 set.seed(123) # for repeatability mycovs = data.frame(outcome = rnorm(100,20,5), race = rep(c("white","black","hispanic","other"),25),

首先是一些数据。为协变量和我感兴趣的回归结果创建一个数据框架,为解释变量创建一个数据框架

我正在做的是逐步通过
lm(结果~mycovs+beta的第I列)
,在本例中,收集残差

set.seed(123) # for repeatability
mycovs = data.frame(outcome = rnorm(100,20,5),
                    race = rep(c("white","black","hispanic","other"),25),
                    income = rep(c("high","low"),50), 
                    age = rnorm(100,30,3))
betas = data.frame(replicate(10000,rnorm(100,50,6)/100))
为了对
betas
中的每个变量执行此操作,我编写了以下代码:

get_resids <- function(x){
  mydata = cbind(mycovs,x)
  cpg = names(mydata)[ncol(mydata)]
  as.vector(resid(lm(formula(paste("outcome ~ as.factor(race) + as.factor(income) + age + ", cpg )),
                     data = mydata)))
  }
head(get_resids(betas[1]))
[1] -1.8525090 -0.7299173  6.4941289  0.5357159 -0.1771154  7.7554550
不错。我正在做10000次回归,并将它们的残差存储在一个矩阵中,这需要20秒多一点的时间。请注意,这是一个单线程操作,按顺序逐步执行10000次回归

嗯,这些暴露实际上是基因CpG甲基化评分,我有大约一百万个要做,所以我想用
foreach()
doParallel
来处理这个问题,但我一直无法弄清楚

这就是我试过的。我首先将betas矩阵分解为4个命名数据帧,每个部分有1/4列:

mylist <- list(b1 = betas[1:2500], b2 = betas[2501:5000], b3 = betas[5001:7500], b4 = betas[7501:10000])
names(mylist); length(mylist)
[1] "b1" "b2" "b3" "b4"
[1] 4

这里的问题是
mylist[i]
正在访问长度为1的子列表(不是存储在列表第i个元素中的数据帧;您需要
mylist[[i]]

因此,您可以使用:

myresids_par <- foreach(i = 1:length(mylist), .combine = "cbind") %dopar% {
  do.call(cbind, lapply(mylist[[i]], get_resids))
}

myresis\u par感谢您解决了我的问题。我将注意到,
foreach()
能够自动解析列。因此,我最终不必手动创建列表对象。您的解决方案和
myresids\u par
myresids_par <- foreach(i = 1:length(mylist), .combine = "cbind") %dopar% {
    do.call(cbind, lapply(mylist[i], get_resids))
  }
stopCluster(cl)
> dim(myresids_par)
[1] 100   4
> head(myresids_par)
             b1         b2         b3          b4
[1,] -1.1051559 -3.2815443 -4.0951682 -2.97181934
[2,] -1.7884883 -1.5842009 -2.2403507 -1.48095064
[3,]  6.0211664  6.8417766  7.0208282  6.93438155
[4,] -0.4692244  0.1247481  0.9653631 -0.08206986
[5,] -0.1857339  0.2945526  1.8936715  0.30034781
[6,]  8.7706564  7.9744631  8.5240021  8.05232223
myresids_par <- foreach(i = 1:length(mylist), .combine = "cbind") %dopar% {
  do.call(cbind, lapply(mylist[[i]], get_resids))
}
myresids_par <- foreach(i = seq_along(mylist), .combine = "c") %dopar% {
  lapply(mylist[[i]], get_resids)
}