流程控制語句在任何語言中都是非常重要的,通過流程控制語句編程者能夠根據業務邏輯在程序中設計合理的循環、分支,實現程序各種各樣強大的功能。一般實現任一算法的控制結構都可以分爲順序結構、分支結構、循環結構及其混合。在R語言中,流程控制語句主要有if else
、for
、while
、switch
、repeat
等,這些流程控制語句本身在許多語言中都是相似的,最重要的是注意其在不同語言中的語法特性。
順序結構
所謂順序結構,即是實現一個算法或者一個功能,要先做什麼,再做什麼一條條依次從上到下寫下來,這是算法實現的基本結構。分支、循環結構中也往往包含順序結構;順序結構中往往也可能由一系列分支、循環結構構成。
比如,我要實現一個功能:尋找三個數的最大值,那麼假設我們三個數分別是 a, b, c
,那麼我們是不是可以一個個依次去比較,最後得出最大值:如果a<b, 那麼就讓a=b, 這樣a就是 a、b中更大的了;接着,如果a>c, 那麼a就是三個數的最大值,返回結果;如果a<c,則c是三個數的最大值,返回結果c的值。這整一個實現,就是一個順序結構。(Ps. 但是整個順序結構又會由幾個分支結構組成,分支結構我們下面討論)
ThreeMax<-function(a, b, c)
{
if(a<b){
a = b
}
if(a>c){
return (a);
}
else{
return (c);
}
}
d <- ThreeMax(5,6,3)
# [1] 6
分支結構
顧名思義,所謂分支結構就是程序在處理不同情況採取不同的措施的一種結構。比如,上面例子中的如果a>c,則返回a;反之,返回c,這就是一種分支結構。在R語言中,實現分支結構有關鍵字switch
、if else
、stopifnot
。
if else
if else
在上面的例子中也已經有體現了,其使用方式爲:if (條件) 表達式1 else if(條件) 表達式2 else 表達式3,其中條件的值應該是一個標量的真或假值;表達式則是在對應條件下的邏輯代碼。不妨,再舉個例子,如身高高於180爲tall,165-180爲middle,低於165爲short,則實現代碼如下:
height = 187
if(height>=180){
cat("Tall\n")
} else if(height <165){
cat("Short\n")
} else{
cat("Middle\n")
}
# Tall
另外值得關注的是函數ifelse()
,它可以根據一個邏輯向量中的多個條件, 分別選擇不同結果,如:
x <- c(-2, 0, 1)
y <- ifelse(x >=0, 1, 0); print(y)
# 0 1 1
switch
switch在R語言中是以switch(EXPR, ...)
函數來實現的,這一點和比如C++將switch作爲關鍵字實現不太一樣,但是做的事情都是一樣,即根據EXPR
的值決定所做的操作,我們可以看個例子:
ccc <- c("b","QQ","a","A","bb")
# note: cat() produces no output for NULL
for(ch in ccc)
cat(ch,":", switch(EXPR = ch, a = 1, b = 2:3), "\n")
# 輸出
b : 2 3
QQ :
a : 1
A :
bb :
for(ch in ccc)
cat(ch,":", switch(EXPR = ch, a =, A = 1, b = 2:3, "Otherwise: last"),"\n")
b : 2 3
QQ : Otherwise: last
a : 1
A : 1
bb : Otherwise: last
即根據EXPR
的值,去尋找後面屬性有沒有與之相匹配的屬性,如果有則做相應屬性所對應的操作並返回值;反正返回缺省值(如上例中的"Otherwise: last")
循環結構
循環結構功能非常強大,比如我們要找任意個數的最大值,那麼我們就需要用到循環結構。在R語言中,循環結構主要包括for
、while
、repeat
三個關鍵字,以下是三個循環關鍵字的功能比較:
循環類型和描述 |
---|
repeat循環多次執行一系列語句,並簡化管理循環變量的代碼。 |
while循環在給定條件爲真時,重複語句或語句組。 它在執行循環體之前測試條件。 |
for循環像while語句,不同之處在於它測試在循環體的端部的條件。 |
for
for
循環功能強大,可以對向量每個元素、矩陣每行、矩陣每列進行循環處理,基本使用方法是:for(循環變量 in 序列) 語句 ,假設我們要循環處理一個向量,如果向量元素大於0,我們標記1;向量元素小於0,我們就標記0:
x <- rnorm(5)
y <- numeric(length(x))
for(i in 1:5){
if(x[i]>=0) y[i] <- 1 else y[i] <- 0
}
print(y)
其中rnorm(5)
會生成5個標準正態分佈隨機數。 numeric(n)
生成有n個0的數值型向量(基礎類型爲double)。如果想對一個向量的下標進行循環,我們可以藉助seq()
函數來完成,同上例我們可以這樣寫:
x <- rnorm(5)
y <- numeric(length(x))
for(i in seq(along.with=x)){
if(x[i]>=0) y[i] <- 1 else y[i] <- 0
}
print(y)
while
實際上while
語句和for
語句非常相似,基本使用模式爲:while(循環條件) 語句 ,當循環條件滿足時,則執行語句,否則退出循環,我們不妨用while來實現以下上面的例子:
x <- rnorm(5)
y <- numeric(length(x))
i = 1
n = length(x)
while(i<=n){
if(x[i]>=0) y[i] <- 1 else y[i] <- 0;
i = i+1;
}
print(y)
repeat
repeat
循環稱爲無條件循環其循環體內的代碼段的執行,一般配合if
語句跳出循環,在R語言中escape 循環有兩個關鍵字,分別是next (相當於C語言中的continue,跳過循環的當前迭代而不終止循環) 和 break (終止循環跳出循環體)。我們先for循環解釋一下這兩個關鍵字:
for(i in 1:10){
if(i=5){
break;
}
print(i);
}
# 只會輸出 1-4
for(i in 1:10){
if(i=5){
next;
}
print(i);
}
# 除了4,其他都會輸出
我們在回到repeat
本身,我們可以利用它來計算整數前100之和,實現代碼如下:
i = 1
sum = 0
repeat{
sum = sum + i;
i = i + 1;
if(i==100) break;
}
print(sum)
# 4950
寫在篇尾
okay,R語言流程控制的主要內容就是這些啦,總體來說很簡單,但是也很重要,只有掌握這些基本的流程控制語句你纔可能會編程。更多R語言相關文章: