流程控制 代表在程式執行時,指令、子程式或求值的順序。如果有寫過程式的人,應該會相當熟悉這類手法(for, while, if else),以上就是所謂流程控制的指令。
在R裡面,流程控制的指令主要可以分為三類:
>
、<
、==
、!=
、%in%
、&
、|
、!
if
、else
、ifelse
、switch
for
、while
、repeat
、break
、next
在資料預處理的過程,或是在建模時使用交叉驗證(CV),常常會需要使用這些指令,協助我們建立一套自動化的分析流程。
在許多主流的程式語言中,流程控制的思維幾乎是必備的!
當然不同語言之間,流程控制的語法不盡相同,可是只要掌握好基本的撰寫邏輯,之後在學習新的程式語言時,是可以一以貫之,只需要花心思和時間在熟悉語法上就可以。
在寫程式的時候,我們時常會需要判斷一些關係是否成立(例如:數字之間的大小關係,某數字是否存在於一個向量…)。
在電機資訊領域(電路),可以想成AND, OR, NOT這類的運算子。換句話說,當關係成立/不成立的時候,我們會得到True
/False
的值,然後時常搭配後面會介紹的「條件指令」一起使用。
# 相信大家小學都學過了!
x <- 5
c(
x > 3 , # 1.大於
x >= 3 , # 2.大於等於
x < 3 , # 3.小於
x <= 3 , # 4.小於等於
x == 3 , # 5.等於
x != 2 # 6.不等於
)
## [1] TRUE TRUE FALSE FALSE FALSE TRUE
# 在R裡面,判斷某個值(或向量),是否存在於另一個向量之中,會使用 %in% 的符號
# 以往在判斷這類情況時,我們往往需要寫迴圈(for-loop),一一將向量裡面的element拿出來,比對看是否成立
# R無疑提供了一個相當好用的運算子!
x <- 5
y <- c(0,2,3)
x %in% c(1,2,3,4,5) # 值是否存在向量內
## [1] TRUE
y %in% c(1,2,3,4,5) # 向量內的各值,是否存在於另一個向量內
## [1] FALSE TRUE TRUE
# 和電路中AND, OR, NOT的概念幾乎相似
x <- 5
y <- 8
# 括號內是True
!(x > 3) # NOT :非;否定(!)
## [1] FALSE
# (True, False)
x > 3 & y > 10 # AND:和;交集(&)
## [1] FALSE
# (True, False)
x > 3 | y > 10 # OR :或;聯集(|)
## [1] TRUE
# &和&&的區別:
c(T,T,T) & c(F,T,T) # 用一個&,會將向量內的每一個元素互相比對,判斷是True/False
## [1] FALSE TRUE TRUE
c(T,T,T) && c(F,T,F) # 用兩個&,只會將向量內的「第一個元素」互相比對而已
## [1] FALSE
我們時常會遇到以下狀況:當「某些條件」成立時,要做A;反之,則做B的情況。
在生活中,這類的例子比比皆是。比方說,如果今天下雨的話,我就帶傘出門;反之,則不帶出門。在這個例子裡,「今天下雨」就是所謂的條件,「帶傘」就是A,「不帶傘」就是B。
在R裡面,主要有三種運用條件指令的方法:
# 語法格式
if('條件'){
'做A'
}else{
'做B'
}
# 多行寫法
if(3 > 2){
TRUE
}else{
FALSE
}
## [1] TRUE
# 單行寫法
if(3 > 2) TRUE else FALSE
## [1] TRUE
# 語法格式
ifelse('條件', '條件若成立:做A', '條件若不成立:做B')
ifelse(2 > 3, T, F)
## [1] FALSE
# 語法格式
switch('指定執行第幾行/哪個名稱的程式碼',
'第一行:做A',
'第二行:做B',
'第三行:做C',
'第四行:做D',
...
)
# 指定第幾行
switch(2, # 指定執行第二行程式碼,故回傳4。(請自行修改數字,看不同的結果)
1+1, # 第一行:1+1
2^2, # 第二行:2的平方
3*6) # 第三行:3*6
## [1] 4
# 指定名稱
switch("Tom", # 指定執行名稱為Tom的這行程式碼,故回傳7 (請自行修改名稱,看不同的結果)
Tom = 2+5,
Susan = 1*0,
Helen = "Apple",
Lee = 1024)
## [1] 7
在處理資料的時候,我們時常會需要不斷重複相同的動作,這時候會需要使用到迴圈指令。
在R裡面,主要迴圈有for
、while
以及repeat
,並且搭配break
(跳出迴圈)和next
(省略此次迴圈,執行下一次迴圈)來創造彈性的應用。
# 計算 1+2+3+4...+135 的值是多少?
result <- 0
for(i in c(1:135)){ # for-loop裡,i會依序帶入1~135的值,重複進行括號內的程式碼
# 迴圈內重複進行的動作
result <- result + i
}
result
## [1] 9180
# 計算 1+2+3+4...+135 的值是多少?
i <- 1
result <- 0
while(i < 136){ # while-loop當符合裡面的條件時,就會一直重複括號內的程式碼,直到不符合為止
# 迴圈內重複進行的動作
result <- result + i
i <- i + 1
}
result
## [1] 9180
# 計算 1+2+3+4...+135 的值是多少?
i <- 1
result <- 0
repeat{ # repeat和while很像,差別在於條件可以寫在任何地方,並且使用break跳出迴圈
if(i > 135) break # 當i比135大時,用break跳出迴圈
# 迴圈內重複進行的動作
result <- result + i
i <- i + 1
}
result
## [1] 9180
# break 主要用來跳出迴圈
for(i in c(1:5)){
if(i == 3) break # 當i等於3的時候,跳出迴圈
# 迴圈內重複進行的動作
print(i)
}
## [1] 1
## [1] 2
# next 主要用來省略此次迴圈的行為,直接進入下一次迴圈
for(i in c(1:5)){
if(i == 3) next # 當i等於3的時候,省略此次迴圈(skip)的動作,從下一個i=4開始
# 迴圈內重複進行的動作
print(i)
}
## [1] 1
## [1] 2
## [1] 4
## [1] 5
流程控制的基本概念和寫法相當簡單,在資料分析的過程中是相當重要的技巧之一。
「條件」的判斷,釐清有哪些動作是「重複」的,或是複合式的運用,這些都是在撰寫相關的程式碼前,就需要先思考過的事情,十分需要相當清晰的邏輯思考能力。
除此之外,唯有多加練習、累積自己的經驗,才能達到「彈性運用、符合自己的需求」的境界。
It’s still a long way to go~