我要解决的问题是需要并行计算才能获得比传统的“ for循环”更快的结果。
问题出在这里
我需要为列表对象内数据框中包含的198135个结果变量生成线性模型。我必须将模型中每个预测变量的所有beta和p值以及它们的拟合优度存储在数据库中。
我编写了一个可以正常完成任务的功能性“ for循环”,但完成该过程需要35个小时以上。我知道R使用的我的8核CPU不到20%,我想全部使用。问题是我不知道如何利用并行计算在foreach循环中转换for循环。
以下是我的问题的一些示例代码:
library(tidyverse)
library(broom)
## Example data
outcome_list <- list(as.data.frame(cbind(rnorm(32), dataframe_id = c(1))),
as.data.frame(cbind(rnorm(32), dataframe_id = c(2))),
as.data.frame(cbind(rnorm(32), dataframe_id = c(3)))) ## This represents my list of 198135 dataframes
mtcars <- mtcars #I will use the explanatory variables from here
## Below this line is my current solution with a for loop that works fine
x <- list()
results_df <- as.data.frame(cbind(dataframe_id = c(0), intercept = c(0),
b_mpg = c(0), p_mpg = c(0),
b_cyl = c(0), p_cyl = c(0),
p.model = c(0), AIC = c(0),
BIC = c(0)))
for(i in 1:3){
x[[i]] <- lm(outcome_list[[i]]$V1 ~ mtcars$mpg + mtcars$cyl)
gof <- broom::glance(x[[i]])
betas <- broom::tidy(x[[i]])
results_df <- rbind(results_df, c(outcome_list[[i]]$V2[1],
betas$estimate[1],
betas$estimate[2], betas$p.value[2],
betas$estimate[3], betas$p.value[3],
gof$p.value, gof$r.squared, gof$AIC,
gof$BIC))
if(i %% i == 0){
message(paste(i, "of 3")) # To know if my machine has not crashed
x <- list() # To keep RAM clean of useless data
}
gc()
}
results_df <- results_df[-1, ]
使用上面显示的代码,我得到了所需的结果(一个具有回归参数的数据框,并且列表中的每个结果变量都拟合良好),但是它很慢,因为我无法使用所有电脑功能。
我知道使用“ foreach”和“ doParallel”软件包可以更快地解决此问题,但是我仍然不了解foreach循环结构背后的逻辑,因为这是我第一次需要处理这么多的循环数据。
PS:我已经尝试过几种foreach函数的方法,但是我什么都没得到。我没有写foreach解决方案的空缺,因为我不了解自己在做什么。
答案 0 :(得分:0)
您可以这样做:
## Example data
outcome_list <- list(as.data.frame(cbind(rnorm(32), dataframe_id = c(1))),
as.data.frame(cbind(rnorm(32), dataframe_id = c(2))),
as.data.frame(cbind(rnorm(32), dataframe_id = c(3))))
## Parallel code
library(doParallel)
registerDoParallel(cl <- makeCluster(3))
results_list <- foreach(i = 1:3) %dopar% {
mylm <- lm(outcome_list[[i]]$V1 ~ mtcars$mpg + mtcars$cyl)
gof <- broom::glance(mylm)
betas <- broom::tidy(mylm)
c(outcome_list[[i]]$V2[1],
betas$estimate[1],
betas$estimate[2], betas$p.value[2],
betas$estimate[3], betas$p.value[3],
gof$p.value, gof$r.squared, gof$AIC,
gof$BIC)
}
stopCluster(cl)
results_df <- setNames(as.data.frame(do.call("rbind", results_list)),
c("dataframe_id", "intercept", "b_mpg", "p_mpg",
"b_disp", "p_disp", "p.model", "AIC", "BIC"))
您将结果返回到foreach(类似于lapply)中,而不是增长对象(在并行BTW中是不可能的)。
详细了解如何使用foreach there。