目录
- 0.问题导入
- 1.for循环函数
- 2.while循环函数
- 3.foreach函数(不并行)
- 4.foreach函数(并行)
- 5.apply函数
- 6.刺激的,来来来,我们用不同大小的矩阵来竞竞速
- 7.总结
- 8.本篇所用的R-packages(没有的需要用install.packages()进行安装)
- 9.致谢
- 10.号外!TheWhoOPs平台与全国地研联公众号实现线上战略合作
0.问题导入
前边我们有讲到R语言中的逻辑判断,可以说这是R语言数据处理中的一个开关,来控制电脑完成一系列操作。而我们会在数据处理过程中遇到将同一种操作/处理方法(如某一指标的计算)在不同的数据上(如不同气象站点的观测序列)进行实现。为了实现这一需求,我们则需要循环遍历来实现。那么,今天我们就来说说R语言中循环遍历,以及其与并行的那些事。
不过,今天我们来点刺激的,以给不同大小矩阵逐行求均值为例来给以下几个函数竞个速!
1. for循环函数
1.1 for函数基本结构
其中a,b分别为i循环的上界与下界,中括号中为需要循环遍历的操作。
for(i in a:b){
action
}
1.2 for循环求矩阵逐行均值算法
其中mean_by_for 类似于一个空箱子,需要在for循环期间不停地装新计算出来的结果temp。c() 函数用于拼接老的向量mean_by_for 与新向量temp.
mean_by_for = 1
for(i in 1:nrow(mat)){
temp = mean(mat[i,])
mean_by_for = c(mean_by_for,temp)
}
mean_by_for = mean_by_for[-1]
2. while循环函数
2.1 while 函数结构
- i = 1为 i 的初始值。
- i <= b 为while 循环的循环条件,是不是布尔条件呢?嘿嘿
- action 为循环的操作
- i = i + 1 为while循环的更新算子
i = 1
while(i <= b){
action
i = i +1
}
2.2 while循环求矩阵逐行均值算法
mean_by_while = 1
while(i <= nrow(mat)){
temp = mean(mat[i,])
mean_by_while = c(mean_by_while,temp)
i = i+1
}
mean_by_while = mean_by_while[-1]
3. foreach函数(不并行)
后面会有一期专门讲foreach 函数的自定义用法,今天拿过来竞速,重点结构在于讲R语言中循环与遍历的基础算法while 与for哈~
mean_by_foreachdo <- foreach(i = 1:nrow(mat),.combine = c) %do% mean(mat[i,])
4. foreach函数(并行)
cl <- makeCluster(2)
registerDoParallel(cl)
mean_by_dopar <- foreach(i = 1:nrow(mat),
.combine = c) %dopar% mean(mat[i,])
stopCluster(cl)
5. apply函数
5.1 apply 函数结构
apply 函数我们在上一期(蓝字传送门:点我复习上期)中有用到过,我们来讲下他的结构与用法。
其中,
- m为矩阵。对,apply函数是专门为矩阵定制的计算方法,matrix only~
- 1 or 2, 1表明在矩阵m中逐行执行function操作; 2表明在矩阵m中逐列执行function 操作。
- function,自定义的各种骚操作,it is!
apply(m, 1(或者2), function)
5.2 apply 函数求矩阵逐行均值算法
mean_by_apply = apply(mat,1,mean)
6. 刺激的,来来来,我们用不同大小的矩阵来竞竞速
6.1 设置赛道(矩阵的大小)
mat1 = round(runif(1000,-100,100))
mat1 = matrix(mat1,nrow = 50)
mat2 = round(runif(10000,-100,100))
mat2 = matrix(mat2,nrow = 500)
mat3 = round(runif(500000,-100,100))
mat3 = matrix(mat3,nrow = 500)
mat4 = round(runif(1000000,-100,100))
mat4 = matrix(mat4,nrow = 5000)
mat5 = round(runif(10000000,-100,100))
mat5 = matrix(mat5,nrow = 50000)
6.2 竞速开始
关注公众号【TheWhoOPs】,后台回复“竞速”获取竞速函数race()
time1 = race(mat1)
time2 = race(mat2)
time3 = race(mat3)
time4 = race(mat4)
time5 = race(mat5)
6.3 竞速结果分析
可视化代码
type = c('for','while','foreachdo','foreachdopar','apply')
size = c(length(mat1),
length(mat2),
length(mat3),
length(mat4),
length(mat5))
time = round(c(time1,time2,time3,time4,time5)*1000,3)
df = data.frame(
type = rep(type,5),
size = rep(1:5,each = 5),
time = time
)
df$type = factor(df$type, levels = type)
df$size = factor(df$size,labels = as.character(size))
p = ggplot()+
geom_line(data =df, aes(x = size, y = time/1000,color = type))+
scale_x_continuous(labels = as.character(size))+
xlab("Size")+
ylab('Time (s)')+
theme_bw()
png('plot_race1.png',
height =15,
width = 15,
units = 'cm',
res = 800)
print(p)
dev.off()
图1 多种函数竞赛结果
由图1 可以看到,在样本大小在数据长度小于500000个的时候,各种算法无比较显著的区别,因为几乎都很小,我们可以接受,感官上基本上都是 chua 的一下就好了。但当长度大于500000个的时候,foreach(do)与foreach(dopar)函数的计算时间就开始与大家出现比较明显的差别。这时,apply, for 与while计算时间还是没有明显差距。而当长度大于1000000时,for与while就显著大于了apply的运行时间,目测是apply运算时间的100倍。
综上,在面向矩阵做循环与遍历某项操作(单变量输入,多变量有时无法使用apply,可能需要自定义函数)的时候,apply函数完胜!
7. 总结
本篇主要讲了以下内容:
- R语言中的for与while循环与遍历结构(重点掌握)
- R语言中的apply函数(重点掌握)
- 以逐行计算矩阵均值为例,比较了R语言中不同遍历方法面向矩阵的运行效率,分析了不同数据大小时各个函数的表现,总体apply函数全胜!
8. 本篇所用的R-packages(没有的需要用install.packages()进行安装)
library(doParallel)
library(foreach)
library(ggplot2)
9. 致谢
首先,感谢大家的持续关注,小编会继续努力,持续更新下去的!
大家如果觉得有帮助啊,还麻烦大家关注点赞,也可以扩散到朋友圈,多多引导朋友加入咱们这个技术平台, 代码共享推动科研进程, 多谢大家啦~
大家如果在使用本代码的过程有遇到问题的,可以留言评论,也可以私信我哈~~
祝大家身体健康,多多保重!!
Jersey 小编联系方式
10. 号外!TheWhoOPs平台与全国地研联公众号实现线上战略合作
这是与全国地研联联合推出的第五篇R语言技术推文-基础篇。
从2020年2月10日起,TheWhoOPs技术公众号将与全国地理学研究生联合会公众号(简称地研联)公众号实现全面线上合作。
合作内容主要包括为周一,三的R语言数据数据分析及可视化文章的线上共享发布及每周日的b站技术直播讲解(点击进入直播间)。
如果大家觉得有帮助还劳烦多多帮忙宣传下哈!!
网友评论