R: doParallel foreach с несколькими выводами кадров данных - PullRequest
0 голосов
/ 07 мая 2018

У меня есть функция, которая должна манипулировать тремя фреймами данных, все с различной структурой:

  • a: исходный фрейм данных. Это параметр для моей функции. Мне нужно удалить строки отсюда, при определенных условиях.
  • b: Новый фрейм данных создан в моей функции. Моя функция добавляет все строки здесь.
  • c: еще один новый фрейм данных, созданный в моей функции. Моя функция добавляет все строки здесь.

Чтобы попробовать параллельную обработку, я набрал минимальный код (следующий за этот вопрос и этот блог ), в котором я только сгенерировал b:

# Set up the parallel
registerDoParallel( makeCluster(3L) )

b <- foreach(i = 1:nrow(f), .combine = rbind) %dopar% {
  tempB <- do_something_function()

  tempB
}

Этот пример отлично работает, но мне не хватает двух фреймов данных. Я нашел другие ответы, но я верю, что мой случай отличается:

Я мог бы изменить a на фрейм данных строк, которые впоследствии будут удалены, но мне нужно объединить все tempA только с tempA ... если это имеет смысл. В предыдущих вопросах, которые я связал, они смешивают все результаты.

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

Кажется, что ваша проблема не имеет ничего общего с параллелизмом, а скорее с объединением результатов.

Пример решения того, как я это сделаю (что я считаю наиболее эффективным способом сделать это):

library(foreach)
tmp <- foreach(i = seq_len(32)) %do% {
  list(iris[i, ], mtcars[i, ], iris[i, ])
}

lapply(purrr::transpose(tmp), function(l) do.call(rbind, l))
0 голосов
/ 07 мая 2018

Я нашел это решение до сих пор. Вместо удаления из a я создаю фрейм данных, в котором будут удаляться строки. Я написал функцию объединения:

combine <- function(x, ...) {  
  mapply(rbind, x, ..., SIMPLIFY = FALSE)
}

И мой цикл выглядит примерно так:

# Set up the parallel
registerDoParallel( makeCluster(3L) )

# Loop
output <- foreach(i = 1:nrow(f), .combine = combine, .multicombine = TRUE) %dopar% {
  tempA <- get_this_value()
  tempB <- do_something_function()
  tempC <- get_this_other_frame()

  # Return the values
  list(tempA, tempB, tempC)
}

Затем я получаю доступ к данным, используя output[[1]] и так далее. Однако для этого решения мне все равно придется сделать setdiff или anti_join после цикла, чтобы удалить «нежелательные» строки из a.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...