如何在使用并行应用

时间:2017-12-04 01:29:56

标签: r parallel-processing tidyverse

我有以下函数my_func,它将参数存储在数据框params中,并将一个额外的参数作为另一个df独立indf


library(tidyverse)

my_func <- function (x=NULL,y=NULL,z=NULL, indf=NULL) {
 out <- (x * y *z )
 out * indf
}


params <- tribble(
  ~x, ~y, ~z,
  5,     1,  1,
  10,     5,  3,
  -3,    10,  5
)

indf <- tribble(
  ~A, ~B, ~C,
  100,     10,  1,
  1000,     300,  3,
  20,    10,  5
)


params %>% 
  pmap(my_func, indf=indf)

它生成以下数据框列表:

#> [[1]]
#>      A    B  C
#> 1  500   50  5
#> 2 5000 1500 15
#> 3  100   50 25
#> 
#> [[2]]
#>        A     B   C
#> 1  15000  1500 150
#> 2 150000 45000 450
#> 3   3000  1500 750
#> 
#> [[3]]
#>         A      B    C
#> 1  -15000  -1500 -150
#> 2 -150000 -45000 -450
#> 3   -3000  -1500 -750

我想要做的是使用parallel包运行上述功能。我这样做way

library(parallel)
params %>% 
  lift(mcmapply, mc.cores = detectCores() - 1)(FUN = my_func, indf=indf)

但它产生了以下矩阵。

     [,1]  [,2] [,3]
[1,]  500  1500 -150
[2,] 5000 45000 -450
[3,]  100  1500 -750

如何使用parallel并生成一个数据帧列表,如初始输出?

1 个答案:

答案 0 :(得分:3)

library(parallel)

nc <- max(detectCores() - 1, 1L)

params %>% 
  lift(mcmapply, SIMPLIFY = FALSE, mc.cores = nc)(FUN = my_func, MoreArgs = list(indf = indf))

# [[1]]
#      A    B  C
# 1  500   50  5
# 2 5000 1500 15
# 3  100   50 25
# 
# [[2]]
#        A     B   C
# 1  15000  1500 150
# 2 150000 45000 450
# 3   3000  1500 750
# 
# [[3]]
#         A      B    C
# 1  -15000  -1500 -150
# 2 -150000 -45000 -450
# 3   -3000  -1500 -750

修改

这是一个“清洁”选项,应该更像是使用pmap

nc <- max(parallel::detectCores() - 1, 1L)

par_pmap <- function(.l, .f, ..., mc.cores = getOption("mc.cores", 2L)) {
  do.call(
    parallel::mcmapply, 
    c(.l, list(FUN = .f, MoreArgs = list(...), SIMPLIFY = FALSE, mc.cores = mc.cores))
  )
}

library(magrittr)

params %>% 
  par_pmap(my_func, indf = indf, mc.cores = nc)

# [[1]]
#      A    B  C
# 1  500   50  5
# 2 5000 1500 15
# 3  100   50 25
# 
# [[2]]
#        A     B   C
# 1  15000  1500 150
# 2 150000 45000 450
# 3   3000  1500 750
# 
# [[3]]
#         A      B    C
# 1  -15000  -1500 -150
# 2 -150000 -45000 -450
# 3   -3000  -1500 -750