前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >R语言 控制流:for、while、ifelse和自定义函数function

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

作者头像
1480
发布2019-06-19 14:57:02
4.8K0
发布2019-06-19 14:57:02
举报
文章被收录于专栏:数据分析1480数据分析1480

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

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

  • 语句(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语句连接到一起

代码语言:javascript
复制
#if-else分支控制流语法
if ( test_expression1) {
statement1
} else if ( test_expression2) {
statement2
} else {
statement3
}

示例

代码语言:javascript
复制
#嵌套用法
> 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控制可以理解为一个函数。

代码语言:javascript
复制
#ifelse语法
ifelse(条件表达式, true, false)

示例

代码语言:javascript
复制
> 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表达式决定的。

代码语言:javascript
复制
> 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)匹配后续的参数名(即变量名)时,返回参数的值

代码语言:javascript
复制
#switch语法
switch(字符,参数名1='参数值2',参数名2='参数值2',……"其他")

示例

代码语言:javascript
复制
#当表达式(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循环

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

代码语言:javascript
复制
#语句
for (变量 in 序列/字符集) {语句/表达式}

示例

代码语言:javascript
复制
#依次执行序列/字符集中的每一个数据+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,结束循环

代码语言:javascript
复制
#语句
while (条件) {语句/表达式} #条件为TRUE,执行语句/表达式;否则终止跳出

示例

代码语言:javascript
复制
> 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关键字,结束循环

代码语言:javascript
复制
repeat {code if(条件) break}

示例

代码语言:javascript
复制
> i=100
> sum=0
> repeat 
+ {
+   if(i==0)
+     break
+   sum=i+sum
+   i=i-1
+ }
> print(sum)
[1] 5050
代码语言:javascript
复制

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

3.1 自定义函数编写

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

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

示例1:简单计算

代码语言:javascript
复制
> 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:矩阵计算

代码语言:javascript
复制
> 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文档里

代码语言:javascript
复制
#avgfunction代码
avgfunction = function(x){
sum(x)/length(x)
}

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

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

代码语言:javascript
复制
> 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
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-06-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据分析1480 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档