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

                                                                                                               

【推荐书籍】


  • 6
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值