如何使用doParallel包对(i in 1:100)的循环进行并列化

时间:2018-02-20 15:10:47

标签: r doparallel

我的脚本中有一个复杂的循环,因此花费太多时间到最后(超过1小时)。如果可能,我想使用超过1核心的CPU来减少计算时间。

是否可以使用paralellization来使用我的循环?

généraldatafram

TabR1

带有用于选择每个电台的代码的矢量

vecsandre

功能

copy <- function (m) {
  for (i in 1:m) {
    TEST[[i]] <- TabR1[TabR1$CdStationMesureEauxSurface == vecsandre[i],]
  }
}

获取选择的列表

TEST=list()

library(doParallel)
no_cores <- detectCores() - 1
grappe <- makeCluster(no_cores)
registerDoParallel(no_cores)
system.time(foreach(z=1:10) %dopar% copy(z))
stopCluster(grappe)

我试试这个,但是我收到了一个错误:

  

副本(z)出错:任务1失败 - “objet'TEST'introuvable”

2 个答案:

答案 0 :(得分:0)

在R中,foreach循环与for循环的工作方式不同。考虑一下:

> x = for (i in 1:3) {i^2}
> x
NULL
> y = foreach(i = 1:3) %do% {i^2}
> y
[[1]]
[1] 1

[[2]]
[1] 4

[[3]]
[1] 9

for循环不会返回任何内容。它只是在{}内重复表达式给定次数。您可以捕获这些迭代的结果。

foreach循环更像是一个函数。循环的每次迭代都返回{}中表达式的结果(如果有多个表达式,则返回最后一个表达式)。然后foreach的默认行为是将每次迭代的结果组合到一个列表中并返回该列表。您不能将foreach次迭代的中间结果分配到另一个对象中,因为foreach存在以在(可能)不同的进程中运行每次迭代。此行为可以避免对结果容器的并发访问问题,for没有此问题,因为它是顺序的。

答案 1 :(得分:0)

这是一种矢量化方法 - iris作为一个可重复性最小的例子

keep_vec <- c("setosa", "versicolor")
split_df <- split(iris, iris$Species)
keep_dfs <- split_df[keep_vec]

# $setosa
   # Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1           5.1         3.5          1.4         0.2  setosa
# 2           4.9         3.0          1.4         0.2  setosa
# 3           4.7         3.2          1.3         0.2  setosa
# ...
# $versicolor
    # Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
# 51           7.0         3.2          4.7         1.4 versicolor
# 52           6.4         3.2          4.5         1.5 versicolor
# 53           6.9         3.1          4.9         1.5 versicolor

使用您的数据,请尝试

vecsandre
split_df <- split(TabR1, TabR1$CdStationMesureEauxSurface)
keep_dfs <- split_df[vecsandre]