专栏首页数据分析1480R语言 控制流:for、while、ifelse和自定义函数function

R语言 控制流:for、while、ifelse和自定义函数function

行列引用、条件筛选等可以简单的数据管理,但其在无法有效处理多次、多重、有规律的循环和判断问题,而控制流却可以通过循环、判断、跳错等等操作轻松处理此类问题。

以下概念贯穿控制流张杰的内容,需要首先认识:

  • 语句(statement):单独或组合语句,一般在{}中以;分隔 。例如:{语句1;语句2}
  • 条件(cond): 最常见的是判断一个条件是否成立。如果成立则执行一条语句或者一个代码块,比如上例a是否小于b,如果小于则输出b
  • 表达式(expr):一个数值或字符的求值语句,多用于数据计算过程或赋值
  • 序列(seq):一个数值或者字符序列

目录

1 分支控制

1.1 if-else

1.2 ifelse

1.3 switch

2 循环控制流

2.1 for循环

2.2 while循环

2.3 repeat 循环

3 function函数(一次编写,多次调用,一劳永逸)

3.1 自定义函数编写

3.2 source()文件间调用自定义函数

分支和循环是通用编程语言中常见的两大控制流。其中,分支控制是根据条件表达式的结果,执行不同的代码段;循环控制是根据条件重复执行代码块,为了避免无限循环,可以根据条件结束循环。接下来分别从分支控制和循环控制,对R语言中的控制流做简单讲述。

正文

1 分支控制

1.1 if-else

经典的流程控制关键字是if-else,并可以把多个if-else语句连接到一起

#if-else分支控制流语法
if ( test_expression1) {
statement1
} else if ( test_expression2) {
statement2
} else {
statement3
}

示例

#嵌套用法
> a=5
> b=6
> if (a < b) {a <- -1
+ } else if (a == b) {a <- 0
+ } else {a <- 1}
> print(a)
[1] -1

1.2 ifelse

ifelse控制可以理解为一个函数。

#ifelse语法
ifelse(条件表达式, true, false)

示例

> x <- factor(sample(letters[1:5], 10, replace = TRUE))
> x
 [1] a a c d a b d b d d
Levels: a b c d
> ifelse(x %in% c("a", "b", "c"), x, factor(NA))
 [1]  1  1  3 NA  1  2 NA  2 NA NA

注意:返回值的class属性跟test表达式相同,其mode属性是由 yes 或 no表达式确定的。当ifelse()用于返回Date类型的对象时,返回值是numeric类型,而不是Date类型,这是因为返回值的class是由test表达式决定的。

> dates <- as.Date(c('2011-01-01', '2011-01-02', '2011-01-03', '2011-01-04', '2011-01-05'))
> dates
[1] "2011-01-01" "2011-01-02" "2011-01-03" "2011-01-04" "2011-01-05"
> dates <- ifelse(dates == '2011-01-01', dates - 1, dates)
> dates
[1] 14974 14976 14977 14978 14979

#解决方案是:把返回值的class重新设置为Date类型。
> dates <- as.Date(c('2011-01-01', '2011-01-02', '2011-01-03', '2011-01-04', '2011-01-05'))
> dates
[1] "2011-01-01" "2011-01-02" "2011-01-03" "2011-01-04" "2011-01-05"
> dates <- ifelse(dates == '2011-01-01', dates - 1, dates)
> dates
[1] 14974 14976 14977 14978 14979
> class(dates) <- 'Date'
> dates
[1] "2010-12-31" "2011-01-02" "2011-01-03" "2011-01-04" "2011-01-05"

1.3 switch

如果分支较多,可以使用switch函数实现分支的选择,switch函数的第一个参数是表达式(exp),通常是一个字符串。当表达式(exp)匹配后续的参数名(即变量名)时,返回参数的值

#switch语法
switch(字符,参数名1='参数值2',参数名2='参数值2',……"其他")

示例

#当表达式(exp)匹配后续的参数名(即变量名)时,返回参数的值
> t = "r"
> switch(t,r='re',g='gr',b='bl',"error")
[1] "re"

#如果不匹配任何参数名,switch函数不返回任何值,可以添加一个匿名的参数,
#当表达式(exp)匹配不上任意一个命名参数时,switch函数将返回匿名参数的值:
> t = "xs"
> switch(t,r='re',g='gr',b='bl',"error")
[1] "error"

2 循环控制流

repeat、while和for是常见的循环控制语句。

2.1 for循环

使用迭代器和一个向量参数,在每个循环中,迭代器变量从向量中取得一个值,直到迭代所有得向量

#语句
for (变量 in 序列/字符集) {语句/表达式}

示例

#依次执行序列/字符集中的每一个数据+print语句
> for (i in 1:5) print(letters[i])
[1] "a"
[1] "b"
[1] "c"
[1] "d"
[1] "e"

#依次执行序列/字符集中的每一个数据+表达式+print语句
> for (i in 1:5) {j = j + i; print(c(i,j))}
[1] 1 1
[1] 2 3
[1] 3 6
[1]  4 10
[1]  5 15
> j = 0
> for (i in 1:5) {j = j + i; print(c(i,j))}
[1] 1 1
[1] 2 3
[1] 3 6
[1]  4 10
[1]  5 15
> print(j)
[1] 15

2.2 while循环

先检测条件,如果条件为TRUE,执行code;如果条件为FALSE,结束循环

#语句
while (条件) {语句/表达式} #条件为TRUE,执行语句/表达式;否则终止跳出

示例

> i=5
> while (i >0) {j = i; i=i-1 ; print(c(j,i))}
[1] 5 4
[1] 4 3
[1] 3 2
[1] 2 1
[1] 1 0

2.3 repeat 循环 repeat 循环:先执行代码,遇到break关键字,结束循环

repeat {code if(条件) break}

示例

> i=100
> sum=0
> repeat 
+ {
+   if(i==0)
+     break
+   sum=i+sum
+   i=i-1
+ }
> print(sum)
[1] 5050

3 function函数(一次编写,多次调用,一劳永逸)

3.1 自定义函数编写

R通过function关键字定义函数,函数主要由函数名称,参数,运行的代码块和返回值组成,函数名称是变量,参数是调用函数时需要传递的形式参数;代码块是由由大括号构成,是调用函数时需要执行的代码逻辑;R的函数不需要显式地使用return关键字明确返回值,R函数的计算的最后一个值将自动作为返回值。

#语法
myfunc=function(arg1,arg2,....) #参数
{
表达式/循环/print语句等
return(object)  #返回输出的对象
}

示例1:简单计算

> avg <- function(a,b)
+ {
+ return(mean(c(a,b)))
+ }
> avg(4,5)
[1] 4.5

> avg <- function(a,b)
+ {
+ mean(c(a,b))
+ }
> avg(4,5)
[1] 4.5

示例2:矩阵计算

> mat1<-matrix(c(1:12),nrow = 3,ncol = 4);mat1
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
> mat2<-matrix(c(1:24),nrow = 4,ncol = 6);mat2
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    5    9   13   17   21
[2,]    2    6   10   14   18   22
[3,]    3    7   11   15   19   23
[4,]    4    8   12   16   20   24
> f<-function(x,y)
+ {
+   xcol<-dim(x)[2]
+   yrow<-dim(y)[1] 
+   m<-dim(x)[1]
+   n<-dim(y)[2]
+   if(xcol!=yrow)   #向量乘积的要求
+   {
+     print("error")
+     return(0)
+   }
+   else #if-else语句
+   {
+     mat<-matrix(0,nrow=dim(x)[1],ncol=dim(y)[2])  #首先要定义一个矩阵作为结果矩阵
+     for(i in c(1:m))
+       for(j in c(1:n))
+         mat[i,j]<-sum(x[i,]*y[,j])  
+     return(mat)
+   }
+ }
> f(mat1,mat2) #调用自定义矩阵计算函数
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]   70  158  246  334  422  510
[2,]   80  184  288  392  496  600
[3,]   90  210  330  450  570  690
> mat1%*%mat2  #验证
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]   70  158  246  334  422  510
[2,]   80  184  288  392  496  600
[3,]   90  210  330  450  570  690   

3.2 source()文件间调用自定义函数

在R语言里我们需要借助source()函数。

示例:自定义avgfunction函数并保存到avgfunction.R文档里

#avgfunction代码
avgfunction = function(x){
sum(x)/length(x)
}

source('avgfunction.R') #注意需用引号将文档名引起来,当avgfunction.R与operate.R在同一路径时,不需要加路径

将被调用的函数放置在电脑桌面(C:/Users/ysl/Desktop/),工作目录(C:/Users/ysl/Documents)

> source('avgfunction.R') #因被调用函数与当前工作空间不一致,提示错误
#Error in file(filename, "r", encoding = encoding) : 无法打开链结
#此外: Warning message:
#In file(filename, "r", encoding = encoding) :
# 无法打开文件'avgfunction.R': No such file or directory

#重新调整在source()添加完整的文件路径,即可成功调用
> source('C:/Users/ysl/Desktop/avgfunction.R')
> avgfunction(c(1:20))
[1] 10.5

本文分享自微信公众号 - 数据分析1480(lsxxx2011)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-06-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【案例拆解】如何利用数据分析手段,有效地驱动产品迭代!

    从产品论的角度而言,一款产品从0到1的建立,需要经历五层设计(战略层、范围层、结构层、框架层、表现层)。而从数据分析的角度而言,数据分析由浅至深也分为5层(角色...

    1480
  • 巧用Python搭建你的用户价值模型

    最近在做一个用户评分模型的项目,这个模型的目的就是用来判断用户的价值。希望通过各种指标来给用户综合打分,每个用户最后会得到一个分值,分值越高,说明用户的价值越高...

    1480
  • 干货分享--统计学知识大梳理(第一部分)

    道德经云:”道生一,一生二,二生三,三生万物“。学习知识亦是如此,一个概念衍生出两个概念,两个概念演化出更小的子概念,接着衍生出整个知识体系。

    1480
  • html5 jqueryrotate插件实现旋转动画

    CSS3 提供了多种变形效果,比如矩阵变形、位移、缩放、旋转和倾斜等等,让页面更加生动活泼有趣,不再一动不动。然后 IE10 以下版本的浏览器不支持 CSS3...

    xiangzhihong
  • DevOps工具介绍连载(23)——Cloud Foundry

    Cloud Foundry是业界第一个开源PaaS云平台,它支持多种框架、语言、运行时环境、云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,...

    小老鼠
  • CSS实现8种炫酷按钮

    在各种UI组件库大行其道的今天,大家已经很少自己用CSS去实现一些效果了,久而久之CSS的水平也越来越退步,所以有空还是得练练。今天给大家分享8种炫酷按钮的CS...

    MudOnTire
  • 车车车险组合域名获融资2亿

    中泽嘉盟投资基金领投,顺为资本、宽带资本等投资机构投资2亿完成对联网车险平台“车车车险”B轮融资。创始人张磊表示,本轮融资将继续用于扩大线上线下交易场景、新产品...

    躲在树上的域小名
  • 解决wordpress上传的文件尺寸超过 php.ini 中定义的 upload_max_filesize 值

    上传的文件尺寸超过 php.ini 中定义的 upload_max_filesize 值。

    lollipop72
  • poj-1056-IMMEDIATE DECODABILITY(字典)

    An encoding of a set of symbols is said to be immediately decodable if no code f...

    瑾诺学长
  • SAP 销售条件表增强栏位

           有时遇到一个比较特殊的业务,比如公司间免费订单,既要让价格为0,不读取VK11里创建的价格, 又要让公司间的价格读取VK11,这实际上是有矛盾的,...

    SAP梦心

扫码关注云+社区

领取腾讯云代金券