【问题标题】:R Parallel Programming with Two Loops and Storage Results具有两个循环和存储结果的 R 并行编程
【发布时间】:2019-07-11 09:08:29
【问题描述】:

我有一个涉及两个循环的函数,结果是两个数据列表。

结构

function (){
for (i in 1:50){
    for (j in 1:100){
        "Do something"
        "get results a and b"
        a list
        b list
    }
    "use the series of a and b calculate two parameter A and B"
    "put A and B into their list"
    list A = append(list A, A)
'or'list B = cbind(list B, B)   # I don't know which one is better
}
plot the figure using list A and B

"saving the results"
dataframe = df(listA, listB)
dataframe to csv
}

代码需要模拟5000次,每一步至少需要1分钟:

  1. 我想使用并行编程来运行整个函数;我试过lapply,但它只适用于一个循环,如果我这样做,结果不一致,情节无法工作,即我无法得到结果;

我发现一些并行代码不能在 Windows 上运行,有些不能在 Mac 上运行,我对这些感到困惑......

循环中的每个步骤都是独立的,因此我认为另一种方法是将工作分开以同时执行它们,但我需要不断得到结果(按照它们应该的顺序)。

  1. 要在进一步的绘图要求中使用数据,我需要保存结果,我觉得这个(上)和并行的有问题;

我保存结果的方式看起来一团糟。 比如我想要的是:

A    B
0    0
0.1  1
1.2  4
3    9
6    12
...  ...

但我得到的是:

    V1
0    0   0.1  1  1.2  4   3    9  6    12  ... ...

我不知道如何保存并行编程中的两列数据。

【问题讨论】:

  • 用你的向量在最后你可以matrix(V1, ncol = 2, byrow = TRUE) 得到一个2列矩阵。
  • 嗨,V1 到底是什么意思,因为我没有将任何人命名为 V1,如果这是矢量的默认名称,在哪里更改它?
  • 最后一个输出。将它保存到变量var_whatever 中,并把它放在我之前评论中的V1 的位置。

标签: r foreach parallel-processing


【解决方案1】:

我喜欢将foreach 包用于此类任务(请查看the documentation)。此函数类似于 for 循环,但它适用于集群。因此,每个 for 迭代都是单独完成的,然后再组合起来。我用你正在使用的结构做了一个小例子。你可以为你的任务修改它。

library(foreach)
library(doParallel)
#number of your cluster precessors, i choosed 4
cl <- makeCluster(4)
registerDoParallel(cl)
# use for z=1:10 your range, the .combine declares how to combine your dataframe afterwrads,
#.inorder makes sure it's sorted and the values are in the right order (TRUE is default)
df<-foreach(z = 1:10, .combine=rbind, .inorder=TRUE) %dopar%{
    list_b = list()
    list_a = list()
    for (i in 1:50){
      for (j in 1:100){
        #some random task you are doing
        a = i 
        b = 50-i
      }
      #combining them
      list_b= cbind(list_b, b)
      list_a= cbind(list_a, a)
    }
    #make sure you return the values, otherwise they don't get combined by foreach
    return(do.call(rbind, Map(data.frame, A=list_a, B=list_b)))
}
#foreach returns nested lists, so you can change it to a dataframe easily
df= as.data.frame(df)
View(df)

stopCluster(cl)

【讨论】:

  • 谢谢这是完美的!感谢您的指示和解释。
  • 您好,我已使用foreach 更改了代码。最初我的代码至少需要 8 小时(i5 15% 的使用率),现在它已经运行了 8 小时(8 vcpu 100% 的使用率)并且它仍然继续,似乎并行不起作用?你有什么建议吗?
  • @rewove 在您接受答案之前,您应该测试答案是否真的回答了您的问题
  • @CPak 很抱歉很快就接受了它,但从技术上讲,从 CPU 的使用情况来看,代码是可以并行执行的。只是不明白为什么运行时间根本没有减少。对于 Python 中的 multiprocess 模型,性能直观地提高了,但对于 R 可能需要其他调整?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-05
  • 2013-10-04
  • 2021-05-04
  • 2021-01-03
  • 2011-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多