Как распараллелить сгруппированный мутировать / суммировать в R - PullRequest
1 голос
/ 21 мая 2019

В tidy R, как распараллелить групповой вызов функции summarize (или mutate)?Преобразование в набор данных iris иллюстрирует мою проблему.

Я создал простую функцию - она ​​принимает два числовых вектора в качестве аргументов.Возвращает список с двумя столбцами.

 library(tidyverse)
 geoMaxMean <- function(pLen, pWid){
    list(
      tibble(maxLen = max(pLen), 
             geoMean = sqrt(max(pLen) * max(pWid))))}

Применение этого к ирису

 gIris <- iris %>% 
    as_tibble() %>% 
    group_by(Species) %>% 
    summarise(Cols2 = geoMaxMean(Petal.Length, Petal.Width)) %>% 
    unnest(Cols2)

Дает ожидаемый результат.

Species     maxLen      geoMean
setosa      1.9         1.067708
versicolor  5.1         3.029851
virginica   6.9         4.153312

Как мнераспараллелить вызов geoMaxMean?Я пытался переделать вызов с помощью lappply или foreach, но мне не удалось выяснить это.

Я использую R 3.4.4 на RStudio Pro.

1 Ответ

1 голос
/ 21 мая 2019

Вот кусок кода, чтобы сделать это с помощью пакета pbmcapply. Пакет mcapply также будет работать нормально и будет работать так же, но таким образом вы получите индикатор выполнения, что удобно.

library(tidyverse)
library(magrittr)
library(pbmcapply)

allSpecies <- 
  iris %>%
  pull(Species) %>%
  unique 

geoMaxMean <- 
  function(species, data){
    data <- data[data$Species == species,]
    pLen <- data$Petal.Length
    pWid <-  data$Petal.Width
    rm(data)

    out <- 
      tibble(maxLen = max(pLen), 
             geoMean = sqrt(max(pLen) * max(pWid))
             )
    return(out)
}

nCores <- 
  detectCores() %>%
  subtract(2)

gIris <-
  allSpecies %>%
  as.list %>%
  pbmclapply(geoMaxMean,
             data = iris,
             mc.cores = nCores
             ) %>%
  bind_rows %>%
  tibble("Species" = allSpecies, .)

Ключевым отличием здесь является то, что вы должны переосмыслить то, что входит в функцию, которую вы вводите в распараллеленную функцию apply. Ваш оригинальный фрагмент кода назначил все вычисления функции, а затем попытался сгруппировать все впоследствии. Если вы спроектировали свою функцию для разделения данных на подгруппы, а затем выполнили свои вычисления, распараллелить очень легко, используя список всех меток группировки в качестве входного списка в pbmclapply, и просто предоставьте свои данные в качестве аргумента для функция, а не вход.

Надеюсь, это поможет.

...