20151210 [R基礎與應用] Ch09:流程控制

整理自 R 軟體資料分析基礎與應用 -- Ch09 : 流程控制

[ 筆記內容 ]
  • (一)if 和 else
  • [ 背景知識 ] 條件檢測指令 "if"
  • 1. "if 敘述"
  • 2. 在 "if 敘述" 內加入 "else"
  • 3. "else-if 敘述"
  • (二)switch
  • [ switch 說明 ]
  • (三)ifelse
  • [ ifelse 說明 ]
  • (四)複合型條件檢測
  • [ if、ifelse 和 switch 的複合使用 ]
 
 
 
 

(一)if 和 else

[ 背景知識 ] 條件檢測指令 "if"
  • 要檢測的條件內容都被包括在 "if" 指令後的括號裡,以下為基本的條件檢測符號 (不限於在 if 敘述裡使用)
  1. 等於 ( == )
  1. 小於 ( < )
  1. 小於等於 ( <= )
  1. 大於 ( > )
  1. 大於等於 ( >= )
  1. 不等於 ( != )
  • 如果條件符合,結果為 TRUE ( 數值上為 1 ) >> 執行該指令
  • 條件不符合,結果為 FALSE  ( 數值上為 0 ) >> 不執行該指令
 
  • [ 範例 ] "TRUE" 等同於數值上的 "1";"FALSE" 等同於數值上的 "0"
# 在數值上"TRUE"等同於"1";而"FALSE"等同於"0"
> as.numeric(TRUE)
[1] 1
> as.numeric(FALSE)
[1] 0
>
  • < 執行結果 >
 
# 簡單的條件判斷
> 1 == 1    # TRUE
[1] TRUE
> 1 < 1     # FALSE
[1] FALSE
> 1 <= 1    # TRUE
[1] TRUE
> 1 > 1     # FALSE
[1] FALSE
> 1 >= 1    # TRUE
[1] TRUE
> 1 != 1    # FALSE
[1] FALSE
  • < 執行結果 >
 
 
1. "if 敘述"
  • [ 範例 ] 條件符合 >> 執行括號內的指令;條件不符合 >> 不執行任何指令
> # 建立一個含有 "1" 的變數
> tocheck <- 1
> # 若 tocheck 等於 "1",顯示 "hello"
> if (tocheck == 1)
+ {
+     print("hello")
+ }
[1] "hello"
> # 現在如果 tocheck 等於 "0",則顯示 "hello"
> if (tocheck == 0)
+ {
+     print("hello")
+ }
> # 因為 tocheck 的值為 "1",所以不會顯示任何東西
  • < 執行結果 >
 
 
2. 在 "if 敘述" 內加入 "else"
  • [ 範例 ] "else" 的使用
> # 首先建立函數
> check.bool <- function(x)
+ {
+     if (x == 1)
+     {
+         # 若輸入值為"1"則顯示"hello"
+         print("hello")
+     }
+     else
+     {
+         # 否則顯示"goodbye"
+         print("goodbye")
+     }
+ }
>
> # 確認函數能否正確運行
> check.bool(1)
[1] "hello"
> check.bool(0)
[1] "goodbye"
> check.bool("k")
[1] "goodbye"
> check.bool(TRUE)    # 因為"TRUE"在數值上等同於"1",所以結果會顯示"hello"
[1] "hello"
  • 先建立判斷用的函數
 
  • < 執行結果 >
 
 
3. "else-if 敘述"
  • 用來檢測數個以上的條件
  • [ 範例 ] 檢測多個條件
> check.bool <- function(x)
+ {
+     if (x == 1)
+     {
+         # 若輸入值等於"1",顯示"hello"
+         print("hello")
+     }
+     else if (x == 0)
+     {
+         # 若輸入值等於"0",顯示"goodbye"
+         print("goodbye")
+     }
+     else
+     {
+         # 否則顯示"confused"
+         print("confused")
+     }
+ }
> check.bool(1)
[1] "hello"
> check.bool(0)
[1] "goodbye"
> check.bool(2)
[1] "confused"
> check.bool("k")
[1] "confused"
  • 先建立判斷用的函數
 
  • < 執行結果 >
 
 
 
 

(二)switch

  • 適用於多個以上的條件檢測。
  • [ switch 說明 ]
# 使用範例
switch(x, "a" = "first", "b" = "second", "z" = "last", "c" = "third", "other")
  • 第一個引數:待檢測的值 
  • 在此為 "x"
  • 接下來的引數:為特定值和其對應的結果 
  • 在此為 "a" = "first", "b" = "second", "z" = "last", "c" = "third"
  • 最後一個引數:若沒有給值,代表該引數為預設結果
  • 在此為 "other"
 
  • [ 範例 ] 用 "switch" 建立函數
# 使用 "switch" 建立函數
> use.switch <- function(x)
+ {
+     switch(x, "a" = "first", "b" = "second", "z" = "last", "c" = "third", "other")
+ }
> use.switch("a")
[1] "first"
> use.switch("b")
[1] "second"
> use.switch("c")
[1] "third"
> use.switch("d")
[1] "other"
> use.switch("e")
[1] "other"
> use.switch("z")
[1] "last"
  • < 執行結果 >
 
 
  • [ 範例 ] 將 "switch" 函數賦予數值
  • 如果給予函數的引數為"數值",代表對應到第幾個引數,引數的名稱則會被忽略
  • 若"數值"比引數的數量還大,將會回傳"NULL"
# 賦予引數數值
> use.switch <- function(x)
+ {
+     switch(x, "a" = "first", "b" = "second", "z" = "last", "c" = "third", "other")
+ }
> use.switch(1)
[1] "first"
> use.switch(2)
[1] "second"
> use.switch(3)
[1] "last"
> use.switch(4)
[1] "third"
> use.switch(5)
[1] "other"
> use.switch(6)    # 因為"給予的數值"大於"引數的數量",所以不會回傳任何東西
> is.null(use.switch(6))    # 檢測物件是否為"NULL"
[1] TRUE
  • < 執行結果 >
 
 
 
 

(三)ifelse

  • 可以用在條件檢測或者是 "logical (邏輯)" 測試。
  • 常用在向量化的運算上。
  • [ ifelse 說明 ]
# 使用範例
ifelse("1 == 1", "Yes", "No")
  • 第一個引數:待檢測的條件
  • 在此為 "1 == 1"
  • 第二個引數:檢測結果為 "TRUE" 時所要回傳的值
  • 在此為 "Yes"
  • 第三個引數:檢測結果為 "FALSE" 時所要回傳的值
  • 在此為 "No"
 
  • [ 範例 ] ifelse 檢測方式
> # 檢測是否 "1 == 1" ?
> ifelse(1 == 1, "Yes", "No")
[1] "Yes"
> # 檢測是否 "1 == 0" ?
> ifelse(1 == 0, "Yes", "No")
[1] "No"
  • < 執行結果 >
 
 
  • [ 範例 ] 將 ifelse 用在"向量化"的引數檢測上
> toTest <- c(1, 1, 0, 1, 0, 1)
> ifelse(toTest == 1, "Yes", "No")
[1] "Yes" "Yes" "No"  "Yes" "No"  "Yes"
> # 將檢測的引數用在第二個和第三個引數作為顯示結果
> ifelse(toTest == 1, toTest * 3, toTest)
[1] 3 3 0 3 0 3
> # FALSE 引數中的值會在每次的檢測結果為"FALSE"時顯示
> ifelse(toTest == 1, toTest * 3, "Zero")
[1] "3"    "3"    "Zero" "3"    "Zero" "3"   
> # 讓 toTest 包含"NA"元素,其對應的結果為"NA"
> toTest[2] <- NA
> ifelse(toTest == 1, "Yes", "No")
[1] "Yes" NA    "No"  "Yes" "No"  "Yes"
> ifelse(toTest == 1, toTest * 3, toTest)
[1]  3 NA  0  3  0  3
> ifelse(toTest == 1, toTest * 3, "Zero")
[1] "3"    NA     "Zero" "3"    "Zero" "3"   
  • < 執行結果 >
 
 
 
 

(四)複合型條件檢測

[ if、ifelse 和 switch 的複合使用 ]
  • 三者檢測的條件可以是一般的 "相等性檢測" 或者 "is.numeric"、"is.na" 的結果
  • 可以使用 "邏輯運算子" 檢測更多的關係:
  • "雙符號形式:比較符號兩邊的單一個元素" (只有運算子左邊的條件會被檢測) 
  • 最好用在 "if"
  • "單符號形式:比較符號兩邊的所有元素" (運算子兩邊的條件都會被檢測) 
  •  最好用在 "ifelse"
  • "AND":"&"(單符號) 或 "&&"(雙符號)
  • "OR":"|"(單符號) 或 "||"(雙符號)
 
  • [ 範例 ] 複合式的條件檢測
> a <- c(1, 1, 0, 1)
> b <- c(2, 1, 0, 1)
> # 使用"單符號"檢測 "a" 和 "b" 的每一個元素
> ifelse(a == 1 & b == 1, "Yes", "No")
[1] "No"  "Yes" "No"  "Yes"
> # 使用"雙符號"檢測 "a" 和 "b" 的第一個元素,因此只回傳一個結果
> ifelse(a == 1 && b == 1, "Yes", "No")
[1] "No"
  • < 執行結果 >