版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第3章控制流3.1条件执行3.4并行计算3.2循环3.5练习案例3.3减少显式循环3.6小结第3章控制流R语言是一种块结构程序语言,块(block)由大括号划分。当块只包含一条语句(statement)时,大括号可以省略。多条语句由换行符或者分号分隔,但建议尽量避免使用分号,每行一条语句更易于理解。一般情况下,R语言中的语句按顺序执行。但有时可能希望改变语句执行顺序,如仅在满足特定条件时执行某些语句,或者重复执行某些语句。R语言像C语言等其他编程语言一样,提供了丰富的控制流结构。本章首先介绍条件执行结构,然后介绍循环结构,最后介绍提高代码执行效率的编码技术,包括减少显式循环和并行计算。3.1条件执行3.1条件执行条件执行结构根据特定条件执行不同的分支语句,包括base程序包中的if-else结构、ifelse()和switch(),dplyr程序包中的if_else(),以及data.table程序包中的fifelse()和fcase()等。本节主要介绍base程序包的相关函数。3.1.1if-else结构if-else结构的语法为(演示)。若条件表达式cond为真,则执行true_action语句;若为假,则执行false_action语句。注意,在if-else结构中,cond需为一元逻辑向量,且不能为缺失值(NA),否则会报错(演示)。3.1条件执行3.1.2ifelse()ifelse()是if-else结构的向量化版本。它可以对向量中的每个元素分别进行条件判断,并返回相应的结果(演示)。cond是一个布尔值向量,true_val和false_val也都是向量。当true_val、false_val的长度小于cond的长度时,前者会通过循环补齐(recycle)。该函数返回一个向量。当cond[i]为真时,返回值的第i个元素为true_val[i];若为假,则返回值的第i个元素为false_val[i](演示)。当处理向量且控制流是二分支时,建议使用ifelse(),这有助于提高代码执行效率。3.1条件执行3.1.3switch()除了二分支问题,实际应用中还经常会遇到多分支问题。
switch()可以根据表达式的取值,从多个候选项中返回相应结果(演示)。当表达式为整数时,按位置匹配对应的结果;当表达式为字符串时,按名称匹配对应的结果。
若整数超出范围,或者字符串无法匹配,则返回空值。因此,switch()适用于实现多分支选择结构(演示)。3.2循环3.2循环3.2.1for循环for循环用于按照给定序列依次重复执行语句。for循环重复执行语句,直到循环变量var的值不再出现在序列seq中(演示)。for循环适用于需要按顺序遍历向量、下标或其他序列的情形。循环结构允许多次执行语句。R语言提供的循环结构包括for、while和repeat,循环控制语句包括break和next。3.2循环3.2.2while循环while循环在给定条件cond为真时,重复执行语句(演示)。while循环适用于循环次数不确定、需要根据条件动态判断是否继续执行的情形。使用while循环时,需要确保给定条件能够不为真,否则会导致永久循环3.2.3repeat循环repeat循环会一直执行语句,直到条件语句为真时才通过break语句退出循环。由于repeat循环每次先执行循环体语句,再判断是否满足退出条件,因此repeat循环至少会执行一次(演示)。它适用于需要先执行操作、再判断是否结束的情况。3.2循环3.2.4循环控制R语言的break语句用于在循环体中退出当前循环,并开始执行循环体后续的语句。在多层嵌套循环中,break语句用于停止执行所在层的循环,并开始执行外层循环。next语句则用于跳过当前循环,直接进入下一次循环,类似于其他编程语言中的continue语句(演示)。通过break和next,可以更灵活地控制循环执行过程。它们是循环结构中常用的控制语句。3.3减少显式循环3.3
减少显式循环3.3.1向量化运算向量化是指将函数作用于输入向量的每个元素,返回的结果也是一个向量。R语言中的基本运算符都是向量化的(演示)。R语言的许多内置函数都是向量化的,可以直接对输入向量的每个元素进行变换。例如,sqrt()、log()、sin()、round()等常用的数学函数。基于这些简单向量化函数构建的复杂函数也是向量化的(演示)。以上介绍的循环结构是R语言的显式循环,其具有易于理解和控制的优点。然而,R是解释性语言,相比于编译语言,在执行显式循环时运行效率较低。因此,为了提高R语言的执行效率,应尽量减少显式循环。R语言提供了多种方式来实现迭代循环,包括向量化(vectorize)运算和apply族函数。3.3
减少显式循环3.3.1向量化运算在实际的R语言编程运算时,应尽可能地使用这些内置函数,不要“重复造轮子”。因为这些内置函数调用了高度优化后的C或FORTRAN预编译代码,计算效率高,经过反复应用测试,能够保证计算的正确性。R语言的设计初衷是为了统计计算,其基础计算单元是向量和矩阵。针对它们的一些统计量计算也可以通过内置函数完成,而无须使用循环。sum()、prod()、mean()和sd()可以分别计算向量的和、积、均值和标准差;colSums()和rowSums()可以分别计算矩阵的列和与行和,而colMeans()和rowMeans()可以分别计算矩阵的列均值和行均值(演示)。R语言中,尤其是处理大型数据集时,应尽量减少显式循环。显式循环的速度比向量化函数的速度慢一个数量级以上,而且代码也较为冗长。因此,充分利用R语言的内置向量化函数,不仅可以简化代码,还能提高执行效率。3.3
减少显式循环3.3.2apply族函数另一种代替显式循环的方式是使用apply族函数。apply族函数有多个,包括apply()、lapply()、sapply()、vapply()、tapply()等。这里主要介绍常用的前3个函数:apply()、lapply()和sapply()。apply()可以对矩阵或多维数组的某些维度元素应用函数(演示)。在处理大型数据集的行和列时,应优先使用colSums()、rowSums()、colMeans()和rowMeans()等内置函数(演示)。lapply()返回的列表可以转换为向量或者矩阵。这时,可以选择lapply()的一种方便使用的封装函数sapply(),可以理解为simplifiedapply(演示)。3.3
减少显式循环3.3.2apply族函数apply族函数属于泛函数(functionals)。泛函数是一类将其他函数作为参数输入的函数,它们很好地展示了R语言的函数式编程(functionalprogramming)思想。相比于apply族函数,R语言中的函数式编程工具包purrr提供了更多的一致性、规范性和便利性。map()与lapply()功能类似,都是对向量的每个元素应用函数,并返回列表。purrr程序包也提供了简便的函数,可以返回所需的数据类型3.3
减少显式循环3.3.3
dplyr程序包的向量化函数dplyr程序包提供了高度优化的向量化函数。dplyr程序包中的case_when()可以向量化多重if-else结构(data.table程序包也提供了具有类似功能的fcase()),常用于数据重编码。case_when()语法类似switch()的语法,输入一系列由“~”连接的公式,左边是逻辑表达式,确定满足此条件分支的值,右边是相应的替换值。最后的.default相当于else分支,指定当左边的逻辑表达式都不匹配时的默认返回值(演示)。dplyr程序包中的mutate()可以对数据框中已有的变量进行函数变换,创建新的变量并将其放在最后面。这些变换函数必须是向量化的,作用于变量的每一行观测值。Vectorize()可以将标量函数向量化(演示)。这些函数虽然不一定都能显著提高运行速度,但能够避免显式循环,更符合R语言的向量化和函数式编程思想。同时,它们也更符合现代数据分析中简洁、规范的数据处理方式。3.4并行运算3.4
并行运算R语言支持并行计算(parallel
computing)来提高代码的执行效率和性能。并行计算将任务分割成多个子任务,分别交给独立的计算资源(如同一台计算机的多个核心,或一个集群中不同计算机的多个核心)同时进行处理,最后将结果收集合并,从而加快整体的计算速度。parallel程序包由早期的并行处理包multicore和snow合并而来。它们对应了R语言中进行并行化的两种主要方式:进程复刻(fork)和套接字(socket)通信。multicore功能是复刻当前的R进程,在新的核心上创建R子进程,这种并行化方式仅适用于支持进程复刻的类UNIX系统(如macOS,Linux等),不适用于Windows系统。snow功能是在每个核心上创建一个R进程,然后通过socket网络连接通信,该并行化方式适用于包括Windows的所有系统。3.4
并行运算并行运算可以显著节省时间,mclapply()并行执行的速度约为lapply()串行执行速度的3.5倍,略低于两者计算所用核心数之比(4倍)。对于运行时间较长的计算任务,可以使用pbmcapply程序包中的pbmclapply(),以进度条的形式追踪和可视化mclapply()并行计算的进度(演示)。Sockets通信并行化使用起来更复杂且速度稍慢,其一般使用过程如下(演示):(1)使用makeCluster()创建包含多个核心的集群;(2)由于集群中的每个核心都会创建独立的R进程,因此主R进程中加载的程序包、定义的变量和函数都不会自动继承,需通过clusterExport()导出给所有的R进程;(3)使用parLapply()、parSapply()等函数,将计算任务分发给集群中的不同核心并行计算;(4)并行计算完成后,使用stopCluster()关闭集群,释放计算资源。3.4
并行运算R语言的foreach程序包提供了一种简洁高效的循环方式,可以在显式for循环中并行执行任务,从而提高代码执行效率。实现在循环中并行执行代码,则foreach程序包必须与doParallel等并行后端程序包结合使用。其中,doParallel程序包充当foreach程序包和parallel程序包之间的接口。与sockets通信并行化使用过程类似,用户需使用doParallel程序包中的registerDoParallel()注册并行后端。该函数可以接收makeCluster()创建的集群对象,或者直接指定内核数。foreach循环的语法与for循环的语法类似。foreach()默认返回列表,可通过参数.combine指定函数或函数名对返回结果做进一步合并处理(演示)。3.5练习案例3.5练习案例为监测某传染性疾病的人群感染情况,某地疾病预防控制中心对所在城市的哨点社区人群开展了8轮感染情况调查,数据见第3章-控制流-data.xlsx,sheet为练习案例1的数据集。请使用for循环计算每轮调查的日新增阳性率(%)(即该轮调查期间平均每日的检测阳性率)及其95%CI。数据结构如表3.1所示,其中变量rounds为调查轮次,t_start和t_end为该轮调查起止日期,n_invgt和n_new_pos为该轮调查参与检测的人数和检测阳性人数。
3.5练习案例表3.1某地哨点社区人群某传染性疾病感染监测情况roundst_startt_endn_invgtn_ne
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 小学信息科技人教版(新教材)三年级全一册 第3单元 畅游网络世界 每课教学设计
- 2026年河北省唐山市高考一模演练政治试题含答案
- 装配式建筑构件堆放层数限制
- (正式版)DB15∕T 4373-2026 砒砂岩区坡面水土流失治理技术规程
- 2026年河南省郑州巩义市事业单位联考招聘考试模拟试题及答案解析
- 2026内蒙古锡林郭勒盟二连浩特市招募第二批公益性岗位人员12人笔试备考试题及答案解析
- 2026浙江宁波鄞州区鄞城托育有限公司招聘1人考试参考题库及答案解析
- 2026内蒙古呼和浩特清水河县城发投资经营有限责任公司招聘5人笔试备考试题及答案解析
- 2026南昌市东湖区社会福利院诚招食堂工作人员3人笔试备考题库及答案解析
- 2026年上海市宝山区顾村科技园学校实习教师招募考试备考题库及答案解析
- 2022年上海市闵行区七宝镇社区工作者招聘考试真题及答案
- GB/T 17702-2021电力电子电容器
- 量子力学-81电子自旋态与自旋算符
- DV-PV培训课件:设计验证和生产确认
- 数模和模数转换器-课件
- 小学生血液知识讲座课件
- 部编人教版中考语文试卷分类汇编口语交际与综合性学习
- 钢结构安装专项施工方案(普通钢结构)
- 99S203 消防水泵接合器安装图集
- 路面施工技术全套课件
- DBJ50T-065-2020 民用建筑外门窗应用技术标准
评论
0/150
提交评论