在函数内使用 plyr ldply 与函数并行

Using plyr ldply parallel with function within function

我有一个包含多个 ID 的数据框,我正在尝试对不同的 ID 集执行特征提取。数据如下所示:

    id  x    y 
1 3812 60    7
2 3812 63  105
3 3812 65 1000
4 3812 69    8
5 3812 75   88
6 3812 78   13

其中 id 有大约 200 个不同的值。所以我试图从 (x,y) 数据中提取特征,并且我想并行进行,因为对于某些数据集,按顺序进行可能需要大约 20 分钟左右。现在我正在使用 dplyr:

x = d %>% group_by(id) %>% do(data.frame(getFeatures(., func_args))

其中 func_args 只是函数 getFeaures 的附加函数输入。我正在尝试使用 plyr::ldplyparallel=TRUE 来执行此操作,但是在 getFeatures 中存在问题,我正在使用我编写的另一个函数。因此,当我尝试 运行 并行时,出现错误:

Error in do.ply(i) : 
  task 1 failed - "could not find function "desparsify""
In addition: Warning messages:
1: <anonymous>: ... may be used in an incorrect context: ‘.fun(piece, ...)’
 
 Error in do.ply(i) : 
  task 1 failed - "could not find function "desparsify""

其中 desparsify 是一个自定义函数,用于处理 (x,y) 数据(它有效地将零添加到数据集中不存在的 x 位置)。当我尝试使用包 lsa 中的 cosine 函数时,我遇到了类似的错误。在 R 中调用 external/non-base 函数时有没有办法使用并行处理?

有。查看 parApply 函数系列。我通常使用parLapply。

您需要使用 cl <- makeCluster(number of cores) 设置核心数并将其与您的 ID 向量(可能取决于您的函数如何识别每个 ID 的条目)和您的函数一起传递, parLapply 以生成一个列表,其中将函数的输出并行应用于每个组。

cl <- makeCluster(number of cores)
ids=1:10               
clusterExport(cl=cl,varlist=c('variable name','function name')) ## in case you need to export variable/functions

result=parLapply(cl=cl,ids, your function)
stopCluster(cl)

您没有说明如何设置 plyr 进行并行化,但我想我可以猜到您在做什么。我也猜你在 Windows。这是一个说明正在发生的事情的小型独立示例:

library(plyr)

## On Windows, doParallel::registerDoParallel(2) becomes:
cl <- parallel::makeCluster(2)
doParallel::registerDoParallel(cl)

desparsify <- function(x) sqrt(x)
y <- plyr::llply(1:3, function(x) desparsify(x), .parallel=TRUE)
## Error in do.ply(i) : 
##  task 1 failed - "could not find function "desparsify""

如果您使用 doFuture 而不是 doParallel,未来的基础框架将确保找到 'desparsify',例如

library(plyr)

doFuture::registerDoFuture()
future::plan("multisession", workers = 2)

desparsify <- function(x) sqrt(x)
y <- plyr::llply(1:3, function(x) desparsify(x), .parallel=TRUE)
str(y)
## List of 3
##  $ : num 1
##  $ : num 1.41
##  $ : num 1.73

(免责声明:我是未来框架的作者)

PS。请注意,plyr 是不再维护的遗留包。您可能想查看 future.applyfurrrforeachdoFuture 作为并行化的替代方案。