分類: R

R 流程控制與迴圈

向量化 if 判斷式

一般的 if 判斷式沒辦法直接處理布林向量的判斷,如果將布林向量放進 if 判斷式中,會以第一個元素為準,其餘的元素則會捨棄不用:

if(c(TRUE, FALSE)) message("OK.")
OK.
Warning message:
In if (c(TRUE, FALSE)) message("OK.") :
  條件的長度 > 1,因此只能用其第一元素

若需要一次對一整個布林向量作判斷,可以改用 ifelse 這個函數,其第一個參數為布林向量,第二個參數是條件判斷為 TRUE 時要執行的運算,第二個參數則是條件判斷為 FALSE 時要執行的運算:

ifelse(c(TRUE, FALSE, TRUE), "Good", "Bad")
[1] "Good" "Bad"  "Good"

這是另外一個例子:

x <- c(3:-2)
sqrt(ifelse(x >= 0, x, NA))
[1] 1.732051 1.414214 1.000000 0.000000
[5]       NA       NA

若第二個與第三個參數為向量時,ifelse 就會依照第一個參數的布林向量來取出對應的值:

idx <- rep(c(TRUE, FALSE), 6)
ifelse(idx, 1:3, -1:-6)
 [1]  1 -2  3 -4  2 -6  1 -2  3 -4  2 -6

switch 判斷式

ifelse 的配合之下,雖然可以處理多重條件的判斷,但是這樣的寫法在條件比較多的時候,會顯得比較雜亂:

x <- "mean"
y <- 1:10
if ( x == "mean" ) {
  mean(y)
} else if ( x == "sd" ) {
  sd(y)
} else if ( x == "median" ) {
  median(y)
} else if ( x == "sum" ) {
  sum(y)
}
[1] 5.5

這時候可以改用 switch 的寫法:

switch(x,
  mean = mean(y),
  sd = sd(y),
  median = median(y),
  sum = sum(y))
[1] 5.5

若要處理所有條件都不符合的預設狀況,可以加入一個沒有名稱的參數,這樣在所有條件都不符合時,預設就會傳回該參數值:

z <- "nothing"
switch(z,
  mean = mean(y),
  sd = sd(y),
  median = median(y),
  sum = sum(y),
  99)
[1] 99

如果要執行多行運算式,就要使用大括號包起來:

z <- "custom"
switch(z,
  mean = mean(y),
  sd = sd(y),
  median = median(y),
  sum = sum(y),
  custom = {
    y2 <- y * 1.2 + pi / 2
    prod(sin(y2))
  })
[1] -0.00102691

如果 switch 第一個參數放置的是數值,後續的選項可以不需要指定名稱,這種狀況 switch 會直接取出該數值所對應的參數:

switch(
  3,
  "first",
  "second",
  "third",
  "fourth"
)
[1] "third"

上面這樣的用法就沒有預設的選項可以使用,如果想要使用數值來當作判斷的依據,但是又需要預設選項時,可以採用這樣的做法:

switch(
  as.character(328),
  "328" = "the anser 328",
  "default anser"
)
[1] "the anser 328"

Page: 1 2 3

G. T. Wang

個人使用 Linux 經驗長達十餘年,樂於分享各種自由軟體技術與實作文章。

Share
Published by
G. T. Wang

Recent Posts

[DIY] 自製凡士林火種

這裡介紹如何利用簡單的凡士林與...

3 年 ago

[DIY] 自製火影木葉、砂忍者村標誌雕刻木牌

本篇記錄我用路邊撿來的樟木與龍...

3 年 ago

收集龍眼木修剪枝幹用於木頭工藝

最近打算帶著阿玄做一些木工作品...

3 年 ago

[DIY] 樟木手工自製迷你手裏劍(忍者武器)

本篇記錄阿玄第一次使用木工工具...

3 年 ago

[DIY] 龍眼木手工自製木槌

本篇記錄我用自己砍的龍眼木還有...

3 年 ago

[DIY] 樟木手工自製苦無(忍者武器)

本篇記錄我自己用樟木的枝幹,以...

3 年 ago