【学习】R语言中的并行计算:foreach,iterators, doParallel包

来源:互联网 发布:杰刚队长知乎 编辑:程序博客网 时间:2024/05/22 07:52


我个人的理解,这些包进行并行计算,有点类似控制编译器的并行开关,将数据、循环变量直接的依赖性进行开关设置。


不过R有几个包,可以提升效率和弥补R自身的不足,做大数据很有用。我就说说我每天要用的吧。
如果不使用分布式,那就用ff、bigmemory等几个package。
bigmemory:R的内存管理太烂了,因为很少给程序员管理的权限,这样一来操作系统懒加上R也懒导致常常读入大数据时内存瞬间用完,导致这个R session被强制退出。解决办法就是把常用的大数据提前放在共享内存里。

Rmpi,snow,multicore: 平行运算/多运程运算。 Rmpi最好多看看,是mpi在R里面的实现。这是平行运算的黄金标准。如果你要做大数据的模型,高能运算是必须的。

Rcpp:R与C++的接口。自带的.C和.F也很有用。毕竟R是高等语言,太慢了,基本的方程还是要用低等语言写。如果做统计模型,会有很多inference,这时必须要用低等语言写Log likelihood的方程。

DEoptim,quadqrog,linprog等等线性非线性优化:优化是统计少不了的技术。R里面好的优化包不是太慢就是太烂,你可以用GNU scientific library自己写优化器,或者买一个第三方的比如说IBM。不过很贵哦,

ggplot:不多说了,就是美丽的图片。。。

不是R的:hadoop。近几年,这都是处理大数据的必需品了。


一、foreach包

foreach包是revolutionanalytics公司贡献给R开源社区的一个包,它能使R中的并行计算更为方便。

与sapply函数类似,foreach函数中的第一个参数是输入参数,%do%后面的对象表示运算函数,而.combine则表示运算结果的整合方式。 

(1)基本操作

下面的例子即是用foreach来完成前面的同一个任务。

> library(foreach);
> x <- foreach(i=1:3) %do% sqrt(i);
> x
[[1]]
[1] 1
[[2]]
[1] 1.414214
[[3]]
[1] 1.732051

> str(x)
List of 3
 $ : num 1
 $ : num 1.41
 $ : num 1.73

【注意:】与for循环不同的是,for只返回的是一个数字,是一个值;而foreach返回的是一个list,是全部的值。

> for (i in 1:3) 
+     y<-sqrt(i);
> str(y)
 num 1.73

> x <- foreach(a=1:3, b=rep(10, 3)) %do%
+ {
+     x1<-(a + b);
+     x2<-a*b;
+     c(x1,x2);  
+ }
> str(x)
List of 3
 $ : num [1:2] 11 10
 $ : num [1:2] 12 20
 $ : num [1:2] 13 30

【注意:】 a, b叫循环变量,循环次数取两者中最小的。如下例,取b的循环次数2。

> x <- foreach(a=1:1000, b=rep(10, 2)) %do% {
+     a + b
+ }
> str(x)
List of 2
 $ : num 11
 $ : num 12

(2).combine操作

.combine则表示运算结果的整合方式,常用的操作符有c, rbind, cbind, +, *。注意,+ 和 * 是list的同列操作。 

> x <- foreach(a=1:3, b=rep(10, 3), .combine="c") %do%
+ {
+     x1<-(a + b);
+     x2<-a*b;
+     c(x1,x2);  
+ }
> x
[1] 11 10 12 20 13 30
> x <- foreach(a=1:3, b=rep(10, 3), .combine="rbind") %do%
+ {
+     x1<-(a + b);
+     x2<-a*b;
+     c(x1,x2);  
+ }
> x
         [,1] [,2]
result.1   11   10
result.2   12   20
result.3   13   30
> x <- foreach(a=1:3, b=rep(10, 3), .combine="cbind") %do%
+ {
+     x1<-(a + b);
+     x2<-a*b;
+     c(x1,x2);  
+ }
> x
     result.1 result.2 result.3
[1,]       11       12       13
[2,]       10       20       30
> x <- foreach(a=1:3, b=rep(10, 3), .combine="+") %do%
+ {
+     x1<-(a + b);
+     x2<-a*b;
+     c(x1,x2);  
+ }
> x
[1] 36 60
> x <- foreach(a=1:3, b=rep(10, 3), .combine="*") %do%
+ {
+     x1<-(a + b);
+     x2<-a*b;
+     c(x1,x2);  
+ }
> x
[1] 1716 6000

.combine还可以自己编写函数来实现,如下例:

> cfun <- function(a, b) a+b
> x <- foreach(a=1:3, b=rep(10, 3), .combine="cfun") %do%
+ {
+     x1<-(a + b);
+     x2<-a*b;
+     c(x1,x2);  
+ }
> x
[1] 36 60

.combine还有一些开关可设置(.multicombine,.maxcombine, .inorder),如整合的参数个数,最大整合的参数格式,参数间的整合是否按次序来等等。 


二、iterators包

iterators包用来指定foreach中的循环因子,常用的函数有irnorm(返回一个特定的循环次数),它可以边计算边产生循环次数(on-the-fly),而不是一开始就全部产生,这样能节省空间。

iterators用来把循环因子进行切分,以便进行并行计算。具体要用时,还需要深入研究其函数。

> library(iterators)
> set.seed(123)
> x <- foreach(a=irnorm(4, count=1000), .combine='+') %do% a
> a
[1]  1.2674975  1.2145058 -0.6748559  1.1210219   #注意,a只产生了4个数。


三、doParallel包

如果要启用并行,则需要加载doParallel包,并将%do%改为%dopar%。这样一行代码就能方便的完成并行计算了。

%dopar%可以实现多核的并行,多处理器的并行和集群上多节点的并行。

# 启用parallel作为foreach并行计算的后端
library(doParallel)

> foreach(i=4:1, .combine='c') %dopar% {
+     Sys.sleep(3 * i)
+     i
+ }
[1] 4 3 2 1        #默认是按次序(即.inorder=TRUE)执行并行计算。
> foreach(i=4:1, .combine='c', .inorder=FALSE) %dopar% {
+     Sys.sleep(3 * i)
+     i
+ }
[1] 4 3 2 1      #按乱序(即.inorder=FALSE)执行并行计算。



0 0
原创粉丝点击