如何在R中并行化分组的变异/汇总

时间:2019-05-21 15:13:21

标签: r parallel-processing grouping summarization

在整洁的R中,如何并行化分组的summarize(或mutate)函数调用? 对iris数据集的转换说明了我的问题。

我创建了一个简单的函数-它接受两个数值向量作为args。它返回一个带有2列小标题的列表。

 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调用?我尝试使用lappplyforeach重做该呼叫,但无法弄清楚。

我正在RStudio Pro上运行R 3.4.4。

1 个答案:

答案 0 :(得分:1)

这是使用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进行并行化,并简单地将数据作为函数的参数,而不是输入。

希望这会有所帮助。