Как я могу написать функцию объединения для оператора R foreach (), который использует разбиение на itertools, так что я получаю тот же результат, что и оператор R foreach () без разбиения на части itertools?
У меня есть оператор R foreach (), который выполняет вычисление и возвращает список из трех списков.Упрощенная версия, которая дает желаемые выходы, находится ниже в первом блоке кода - она использует функцию объединения, которую я нашел в Сохранение нескольких выходов цикла foreach dopar .
Теперь я хочу запустить этот же код, используя chunking от itertools.Я пробовал это двумя разными способами (см. Второй и третий кодовые блоки ниже), и ни один из них не дал желаемого результата.Проблема состоит в том, что вместо трех списков, состоящих из 3 списков по 10 списков, в обеих моих попытках включить разбиение на itertools, три_листы состоят из 3 списков по 2 списка (с двумя списками разной длины в разных попытках).Я предполагаю, что списки имеют длину 2, а не 10, потому что num_cores на моем компьютере равно 2 - это подсказывает мне, что, возможно, нужно изменить мою функцию объединения, чтобы правильно объединить выходные данные при использовании разбиения itertools.У меня проблемы с выяснением, как это изменить, хотя.Как мне изменить функцию объединения?
Вот оператор foreach (), который генерирует желаемый результат:
# set up
library(foreach)
library(doParallel)
# set parallel options
num_cores_total <- detectCores()
num_cores <- num_cores_total - 2
cl <- makeCluster(spec= num_cores, type="PSOCK")
registerDoParallel(cl, cores = num_cores)
# create function that will separate out foreach output into list of three lists
comb <- function(x, ...) {
lapply(seq_along(x),
function(i) c(x[[i]], lapply(list(...), function(y) y[[i]])))
}
# foreach statement
three_lists <- foreach(i = 1:10, .inorder=TRUE, .combine='comb', .multicombine=TRUE, .init=list(list(), list(), list())) %dopar% {
first_output <- i*1
second_output <- i*10
third_output <- i*100
list(first_output, second_output, third_output)
}
first_output_list <- three_lists[[1]]
second_output_list <- three_lists[[2]]
third_output_list <- three_lists[[3]]
Вот моя первая (безуспешная) попытка включить блокировку itertools вcode:
# set up
library(foreach)
library(itertools)
library(doParallel)
# set parallel options
num_cores_total <- detectCores()
num_cores <- num_cores_total - 2
cl <- makeCluster(spec= num_cores, type="PSOCK")
registerDoParallel(cl, cores = num_cores)
# create function that will separate out foreach output into list of three lists
comb <- function(x, ...) {
lapply(seq_along(x),
function(i) c(x[[i]], lapply(list(...), function(y) y[[i]])))
}
# foreach statement
three_lists <- foreach(thisIter=isplitIndices(10, chunks=num_cores), .inorder=TRUE, .combine='comb', .multicombine=TRUE, .init=list(list(), list(), list())) %dopar% {
first_output <- thisIter*1
second_output <- thisIter*10
third_output <- thisIter*100
list(first_output, second_output, third_output)
}
first_output_list <- three_lists[[1]]
second_output_list <- three_lists[[2]]
third_output_list <- three_lists[[3]]
# stop cluster
stopCluster(cl)
И вот моя вторая (безуспешная) попытка включения фрагментов itertools в код:
# set up
library(foreach)
library(itertools)
library(doParallel)
# set parallel options
num_cores_total <- detectCores()
num_cores <- num_cores_total - 2
cl <- makeCluster(spec= num_cores, type="PSOCK")
registerDoParallel(cl, cores = num_cores)
# create function that will separate out foreach output into list of three lists
comb <- function(x, ...) {
lapply(seq_along(x),
function(i) c(x[[i]], lapply(list(...), function(y) y[[i]])))
}
# foreach statement
three_lists <- foreach(thisIter=isplitIndices(10, chunks=num_cores), .inorder=TRUE, .combine='comb', .multicombine=TRUE, .init=list(list(), list(), list())) %dopar% {
calc_function <- function(x){
first_output <- x*1
second_output <- x*10
third_output <- x*100
return(list(first_output, second_output, third_output))
}
sapply(thisIter, calc_function)
}
first_output_list <- three_lists[[1]]
second_output_list <- three_lists[[2]]
third_output_list <- three_lists[[3]]
# stop cluster
stopCluster(cl)