我正在try 使用foreachdoParallel实现嵌套的for循环,但我不想循环遍历所有值的组合.基本上,我有一个正方形数据集,我想对每一对值运行一个函数,但我不需要重复--例如,我需要计算[1,2]的函数,但不计算[2,1]的函数,因为结果是相同的.这里是一个非常基本的示例,但请注意,由于实际函数/计算的复杂性,我try 使用doParalle.

bvec <- seq(1,10,1)
avec <- seq(1,10,1)

x <- data.frame()
for (i in 1:10) {
  for (j in i:10) {
    x[i,j] <- sim(avec[i], bvec[j])
  }
}
x

原始数据集大约是1800 x 1800,如果我进行所有的成对计算,这将导致超过320万次计算,这是不必要的.以下是我为foreach名选手准备的:

cl <- parallel::makeCluster(detectCores()-4)
doParallel::registerDoParallel(cl)
clusterExport(cl, list("bvec","avec"))  
z <-
  foreach(i=1:10, .combine="cbind") %:%
    foreach(j=i:10) %dopar% {
      x[i,j] <- sim(avec[i], bvec[j])
    }
z
parallel::stopCluster(cl)

是否有可能使用foreach来限制迭代次数?如果没有,有没有其他方法来优化这个过程?

我已try 将Foreach语句更改为

foreach(i=1:10, .combine="cbind") %:%
    foreach(j=i:10) %dopar% {
      x[i,j] <- sim(avec[i], bvec[j])
    }

但这显然行不通.

推荐答案

编辑-下面的 idea 比简单的循环更慢.%DO%比%DAPAR%快.在VEC长度为200的时候,事情变得足够慢了.您将希望对设备上的基本并行进程进行基准测试,以查看并行是否值得继续进行开销.

...

我在1800x1800的数据上运行了microbenchmark,而嵌套的if()三角循环在sum()的计算次数上比outer()快.

这是一种执行foreach嵌套的方法(从文档中取自https://cran.r-project.org/web/packages/foreach/vignettes/nested.html),并结合了计算内循环并跳过半个三角形的重函数的ifelse()技巧.

foreach(b=bvec, .combine='cbind') %:%
    foreach(a=avec, .combine='c') %dopar% {
      ifelse(a>=b, sum(a, b), NA)   # ifelse to skip expesive operation
    }

j=i:10的 idea 和对全局对象的写入与%do%一起工作,但不与%dopar%一起工作,这在该线程https://stackoverflow.com/a/45920140/%do%76092中进行了讨论,并且写道:"[%DOPA%]不改变全局对象[x]"

x <- matrix(NA, nrow = 10, ncol = 10)
foreach(i=1:10, .combine="cbind") %:%
  foreach(j=i:10, .combine="c", .inorder=TRUE) %do% { # %do% works
    x[i,j] <- sum(avec[i], bvec[j])
  }
x

下面的方法是可行的,但会循环使用跳过的值.三角形形状不正确,正确.矩阵魔术从https://stackoverflow.com/a/48988950/10276092开始,使数据略显美观.

aa <- foreach(i=1:10, .combine="cbind") %:%
  foreach(j=i:10, .combine="c", .inorder=TRUE) %dopar% {
    sum(avec[i], bvec[j])
  }
aa[col(aa) + row(aa) > nrow(aa) + 1] <- 0 # drop the recycling
aa

       result.1 result.2 result.3 result.4 result.5 result.6 result.7 result.8 result.9 result.10
 [1,]        2        4        6        8       10       12       14       16       18        20
 [2,]        3        5        7        9       11       13       15       17       19         0
 [3,]        4        6        8       10       12       14       16       18        0         0
 [4,]        5        7        9       11       13       15       17        0        0         0
 [5,]        6        8       10       12       14       16        0        0        0         0
 [6,]        7        9       11       13       15        0        0        0        0         0
 [7,]        8       10       12       14        0        0        0        0        0         0
 [8,]        9       11       13        0        0        0        0        0        0         0
 [9,]       10       12        0        0        0        0        0        0        0         0
[10,]       11        0        0        0        0        0        0        0        0         0

R相关问答推荐

使用lapply的重新定位功能

如何在Chart_Series()中更改轴值的 colored颜色 ?

传递ggplot2的变量作为函数参数—没有映射级别以正确填充美学

如何在R中描绘#符号?

R中的哈密顿滤波

有没有办法使用ggText,<;Sub>;&;<;sup>;将上标和下标添加到同一元素?

在R函数中使用加号

如何将使用rhandsontable呈现的表值格式化为百分比,同时保留并显示完整的小数精度?

QY数据的处理:如何定义QY因素的水平

根据纬度和距离连接两个数据集

如何将一列中的值拆分到R中各自的列中

从数据创建数字的命名列表.R中的框

将具有坐标列表列的三角形转换为多个多边形

将工作目录子文件夹中的文件批量重命名为顺序

如何阻止围堵地理密度图?

附加中缀操作符

如何用不同长度的向量填充列表?

R没有按顺序显示我的有序系数?

根据用户输入更改标记大小和 colored颜色 (R)

在R中,有没有什么方法可以根据一列中的多个值来过滤行?