Я имею дело с проблемой, которая требует параллельных вычислений для получения более быстрых результатов, чем с классическим циклом for.
Вот проблема:
Мне нужно сгенерировать линейные модели для переменных результата 198135 года, содержащихся в кадрах данных в объекте списка. Я должен хранить все значения бета и p для каждой прогнозирующей переменной в моделях в кадре данных, а также их показатели соответствия.
Я написал функционал "for loop", который выполняет задачу должным образом, но для ее завершения требуется более 35 часов. Я знаю, что R использует менее 20% моего 8-ядерного процессора, и я хотел бы использовать все это. Проблема в том, что я не знаю, как преобразовать цикл 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, потому что я не понимаю, что я делаю.