我正在处理一个需要并行计算以获得比经典“for 循环”更快的结果的问题。
问题是这样的:
我需要为列表对象内的数据帧中包含的 198135 个结果变量生成线性模型。我必须将模型中每个预测变量的所有 beta 和 p 值以及它们的拟合优度度量存储在数据框中。
我编写了一个功能性“for 循环”,可以正确完成该任务,但完成它需要超过 35 个小时。我知道 R 使用了我的 8 核 CPU 的不到 20%,但我想全部使用。问题是我不知道如何将 for 循环转换为 foreach 循环以利用并行计算。
这是我的问题的一些较小规模的示例代码:
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 解决方案尝试,因为我不明白我在做什么。