常用內建函數

Everything that happens is a function call.

John Chambers

函數是 R 的核心基石,若是想成為一個中高階的 R 程式設計師、掌握更進階的 R 技術,必須為函數的認知建立一個強大厚實的基礎,事實上早在這個章節之前我們就開始使用函數了,不管是建立向量時使用的 c() 函數或者是檢查向量類型的 class(),都是常用的函數。函數的組成元件有三個:

  1. 輸入與參數(inputs and arguments)
  2. 主體(body)
  3. 輸出(outputs)

在使用已經定義好的內建函數(或者說呼叫函數,function calls)我們只需要在函數名稱後面的小括號內放進輸入與參數,然後執行就可以得到輸出。對初階的使用者來說,對照輸出格式與內容符合所預期的輸入與參數,已經是在使用函數時表現十分成熟的行為;而進階的高級使用者會在閒暇之餘,檢驗函數主體的運算邏輯,提升在學術研討或商業運用上的嚴謹程度。接著來探討一些在處理數值向量(numeric)、處理文字向量(character)與進行描述統計(Descriptive Statistics)上常用的 R 語言內建基礎函數。

# How to call a function
my_function(my_inputs, my_args, ...)
1
2

數值向量函數

數值向量函數可以針對數值向量做處理或運算,常用的有:

  • abs()
  • sqrt()
  • ceiling()
  • floor()
  • round()
  • exp()
  • log()
  • log10()

數值向量函數:abs()

abs() 是能夠將我們輸入數值向量內容都轉換為絕對值的函數。

-5:-1
abs(-5:-1)
1
2
## > -5:-1
## [1] -5 -4 -3 -2 -1
## > abs(-5:-1)
## [1] 5 4 3 2 1
1
2
3
4

數值向量函數:sqrt()

sqrt() 是能夠將我們輸入數值向量內容都開平方根號的函數。

1:5
sqrt(1:5)
1
2
## > 1:5
## [1] 1 2 3 4 5
## > sqrt(1:5)
## [1] 1.000000 1.414214 1.732051 2.000000 2.236068
1
2
3
4

數值向量函數:ceiling()

ceiling() 是能夠將輸入數值向量內容都做無條件進位的函數。

ceiling(9.527)
nums <- sqrt(c(7, 17, 27, 37, 47))
nums
ceiling(nums)
1
2
3
4
## > ceiling(9.527)
## [1] 10
## > nums <- sqrt(c(7, 17, 27, 37, 47))
## > nums
## [1] 2.645751 4.123106 5.196152 6.082763 6.855655
## > ceiling(nums)
## [1] 3 5 6 7 7
1
2
3
4
5
6
7

數值向量函數:floor()

floor() 是能夠將輸入數值向量內容都做無條件捨去的函數。

floor(9.527)
nums <- sqrt(c(7, 17, 27, 37, 47))
nums
floor(nums)
1
2
3
4
## > floor(9.527)
## [1] 9
## > nums <- sqrt(c(7, 17, 27, 37, 47))
## > nums
## [1] 2.645751 4.123106 5.196152 6.082763 6.855655
## > floor(nums)
## [1] 2 4 5 6 6
1
2
3
4
5
6
7

數值向量函數:round()

round() 是能夠調整數值向量內容小數位的函數,以四捨五入規則決定,使用的時候可以多給一個參數 digits,預設 digits = 0,就是調整為整數。

round(9.527)
round(9.527, digits = 0)
round(9.527, digits = 1)
round(9.527, digits = 2)
1
2
3
4
## > round(9.527)
## [1] 10
## > round(9.527, digits = 0)
## [1] 10
## > round(9.527, digits = 1)
## [1] 9.5
## > round(9.527, digits = 2)
## [1] 9.53
1
2
3
4
5
6
7
8

數值向量函數:exp()

exp() 是能夠將輸入數值向量內容調整為以自然對數函數之底數 e 的指數函數,其中 e 接近 2.718282。

nums <- 1:5
exp(nums)
1
2
## > nums <- 1:5
## > exp(nums)
## [1]   2.718282   7.389056  20.085537  54.598150 148.413159
1
2
3

數值向量函數:log()

log() 是能夠將輸入數值向量內容取以 e 為底數的對數函數。

e <- exp(1)
log(e)
log(e**2)
log(e**3)
1
2
3
4
## > e <- exp(1)
## > log(e)
## [1] 1
## > log(e**2)
## [1] 2
## > log(e**3)
## [1] 3
1
2
3
4
5
6
7

數值向量函數:log10()

log10() 是能夠將輸入數值向量內容取以 10 為底數的對數函數。

nums <- c(10, 10**2, 10**3, 10**4, 10**5)
log10(nums)
1
2
## > nums <- c(10, 10**2, 10**3, 10**4, 10**5)
## > log10(nums)
## [1] 1 2 3 4 5
1
2
3

文字向量函數

文字向量函數可以針對文字向量做處理,常用的有:

  • toupper()
  • tolower()
  • substr()
  • grep()
  • sub()
  • strsplit()
  • paste()
  • paste0()
  • trimws()

文字向量函數:toupper()

toupper() 是能夠將輸入文字向量全部轉換為大寫的函數。

skywalkers <- c("Luke Skywalker", "Anakin Skywalker")
toupper(skywalkers)
1
2
## > skywalkers <- c("Luke Skywalker", "Anakin Skywalker")
## > toupper(skywalkers)
## [1] "LUKE SKYWALKER"   "ANAKIN SKYWALKER"
1
2
3

文字向量函數:tolower()

tolower() 是能夠將輸入文字向量全部轉換為小寫的函數。

skywalkers <- c("Luke Skywalker", "Anakin Skywalker")
tolower(skywalkers)
1
2
## > skywalkers <- c("Luke Skywalker", "Anakin Skywalker")
## > tolower(skywalkers)
## [1] "luke skywalker"   "anakin skywalker"
1
2
3

文字向量函數:substr()

substr() 是能夠將輸入文字向量擷取部分的函數,使用的時候搭配兩個參數, start 參數指定要從哪一個字元位置開始擷取, stop 參數指定要擷取到哪一個字元位置。

my_char <- "Learn R the easy way"
substr(my_char, start = 1, stop = 5)
substr(my_char, start = 7, stop = 7)
substr(my_char, start = 9, stop = 11)
substr(my_char, start = 13, stop = 16)
substr(my_char, start = 18, stop = 20)
1
2
3
4
5
6
## > my_char <- "Learn R the easy way"
## > substr(my_char, start = 1, stop = 5)
## [1] "Learn"
## > substr(my_char, start = 7, stop = 7)
## [1] "R"
## > substr(my_char, start = 9, stop = 11)
## [1] "the"
## > substr(my_char, start = 13, stop = 16)
## [1] "easy"
## > substr(my_char, start = 18, stop = 20)
## [1] "way"
1
2
3
4
5
6
7
8
9
10
11

文字向量函數:grep()

grep() 是能夠在文字向量中搜尋指定樣式並將符合指定樣式所在索引值回傳的函數,使用 pattern 參數指定樣式,如果搜尋後沒有符合樣式的,則會回傳 integer(0)

starwars <- c("Luke Skywalker", "Princess Leia Organa", "Anakin Skywalker", "Darth Vader")
grep(starwars, pattern = "Skywalker")
grep(starwars, pattern = "Leia")
grep(starwars, pattern = "Vader")
grep(starwars, pattern = "Yoda")
1
2
3
4
5
## > starwars <- c("Luke Skywalker", "Princess Leia Organa", "Anakin Skywalker", "Darth Vader")
## > grep(starwars, pattern = "Skywalker")
## [1] 1 3
## > grep(starwars, pattern = "Leia")
## [1] 2
## > grep(starwars, pattern = "Vader")
## [1] 4
## > grep(starwars, pattern = "Yoda")
## integer(0)
1
2
3
4
5
6
7
8
9

grep() 函數可以指定參數 ignore.case 為 TRUE,這樣在搜尋樣式的時候會忽略文字的大小寫(預設為 FALSE,不忽略大小寫。)以這個例子來說明的話,原本尋找 "skywalker" 樣式為小寫,所以回傳 integer(0) ,如果加入參數 ignore.case = TRUE 則可以成功搜尋到。

starwars <- c("Luke Skywalker", "Princess Leia Organa", "Anakin Skywalker", "Darth Vader")
grep(starwars, pattern = "skywalker")
grep(starwars, pattern = "skywalker", ignore.case = TRUE)
1
2
3
## > starwars <- c("Luke Skywalker", "Princess Leia Organa", "Anakin Skywalker", "Darth Vader")
## > grep(starwars, pattern = "skywalker")
## integer(0)
## > grep(starwars, pattern = "skywalker", ignore.case = TRUE)
## [1] 1 3
1
2
3
4
5

文字向量函數:sub()

sub() 除了可以像 grep() 函數搜尋指定樣式,搜尋到以後還可以指定替換為其他樣式,使用 pattern 參數指定樣式,使用 replacement 參數指定要替換的文字樣式,以這個範例來說明,我們將 "Anakin" 替換為 "Luke"

anakin <- "Anakin Skywalker"
luke <- sub(anakin, pattern = "Anakin", replacement = "Luke")
luke
1
2
3
## > anakin <- "Anakin Skywalker"
## > luke <- sub(anakin, pattern = "Anakin", replacement = "Luke")
## > luke
## [1] "Luke Skywalker"
1
2
3
4

sub() 同樣可以指定參數 ignore.case = TRUE,在搜尋樣式的時候忽略文字的大小寫(預設為 FALSE,不忽略大小寫。)

anakin <- "Anakin Skywalker"
luke <- sub(anakin, pattern = "anakin", replacement = "Luke")
luke # 取代失敗
luke <- sub(anakin, pattern = "anakin", replacement = "Luke", ignore.case = TRUE)
luke # 取代成功
1
2
3
4
5
## > anakin <- "Anakin Skywalker"
## > luke <- sub(anakin, pattern = "anakin", replacement = "Luke")
## > luke # 取代失敗
## [1] "Anakin Skywalker"
## > luke <- sub(anakin, pattern = "anakin", replacement = "Luke", ignore.case = TRUE)
## > luke # 取代成功
## [1] "Luke Skywalker"
1
2
3
4
5
6
7

文字向量函數:strsplit()

strsplit() 是能夠將一個文字向量切割成清單(list)的函數,使用 split 參數可以指定要根據什麼分割符號來進行文字的切割,值得注意的是這個函數的輸出是以清單的資料結構儲存。

my_book <- "Learn R the easy way"
strsplit(my_book, split = " ")
my_book <- "Learn R, the easy way"
strsplit(my_book, split = ", ")
1
2
3
4
## > my_book <- "Learn R the easy way"
## > strsplit(my_book, split = " ")
## [[1]]
## [1] "Learn" "R"     "the"   "easy"  "way"  
## 
## > my_book <- "Learn R, the easy way"
## > strsplit(my_book, split = ", ")
## [[1]]
## [1] "Learn R"      "the easy way"
1
2
3
4
5
6
7
8
9

文字向量函數:paste()

paste() 是能夠將多個文字向量連結成一個文字向量的函數,使用 sep 參數可以指定連結起來以後要使用什麼分隔符號,預設是以一個空格來連結。

luke <- "Luke"
anakin <- "Anakin"
skywalker <- "Skywalker"
luke_skywalker <- paste(luke, skywalker)
anakin_skywalker <- paste(skywalker, anakin, sep = ", ")
luke_skywalker
anakin_skywalker
1
2
3
4
5
6
7
## > luke <- "Luke"
## > anakin <- "Anakin"
## > skywalker <- "Skywalker"
## > luke_skywalker <- paste(luke, skywalker)
## > anakin_skywalker <- paste(skywalker, anakin, sep = ", ")
## > luke_skywalker
## [1] "Luke Skywalker"
## > anakin_skywalker
## [1] "Skywalker, Anakin"
1
2
3
4
5
6
7
8
9

文字向量函數:paste0()

paste0()paste() 作用相同,但是預設以空字串連結。

sky <- "Sky"
walker <- "walker"
skywalker <- paste0(sky, walker)
skywalker
1
2
3
4
## > sky <- "Sky"
## > walker <- "walker"
## > skywalker <- paste0(sky, walker)
## > skywalker
## [1] "Skywalker"
1
2
3
4
5

文字向量函數:trimws()

trimws() 是能夠將文字向量中多餘空格刪除的函數,而所謂的多餘空格指的是出現在文字左邊的空格(leading blanks)或出現在文字右邊的空格(trailing blanks),至於出現在文字之間的空格,由於多數語言句子的組成都習慣以空格區隔單字,並不算是多餘空格(像是 Luke Skywalker 名字與姓氏之間存在的空格)。加入 which = "left" 參數可以指定刪除左邊多餘空格、 which = "right" 參數可以指定刪除右邊多餘空格,預設 which = "both" 即刪除左邊與右邊多於空格。

luke <- "   Luke Skywalker   "
trimws(luke)
trimws(luke, which = "left")
trimws(luke, which = "right")
1
2
3
4
## > luke <- "   Luke Skywalker   "
## > trimws(luke)
## [1] "Luke Skywalker"
## > trimws(luke, which = "left")
## [1] "Luke Skywalker   "
## > trimws(luke, which = "right")
## [1] "   Luke Skywalker"
1
2
3
4
5
6
7

描述統計函數

常用的描述統計函數都有一個共同的參數 na.rm 能夠將輸入s向量中的遺漏值排除,如果輸入帶有遺漏值,必須要指定 na.rm = TRUE 才能夠回傳答案( na.rm 預設為 FALSE 。)

描述統計函數可以針對向量做摘要,常用的有:

  • unique()
  • mean()
  • sd()
  • median()
  • range()
  • sum()
  • max()
  • min()

描述統計函數:unique()

unique() 是能夠將輸入向量中獨一值回傳的函數。

my_seq <- rep(7, times = 3)
unique(my_seq)
rgb <- c("red", "red", "green", "green", "green", "blue")
unique(rgb)
1
2
3
4
## > my_seq <- rep(7, times = 3)
## > unique(my_seq)
## [1] 7
## > rgb <- c("red", "red", "green", "green", "green", "blue")
## > unique(rgb)
## [1] "red"   "green" "blue" 
1
2
3
4
5
6

描述統計函數:mean()

mean() 是能夠將輸入數值向量平均值回傳的函數。

my_seq <- 1:5
mean(my_seq)
my_seq <- c(my_seq, NA) # 加入一個 NA
mean(my_seq) # 輸出為 NA
mean(my_seq, na.rm = TRUE) # 排除遺漏值
1
2
3
4
5
## > my_seq <- 1:5
## > mean(my_seq)
## [1] 3
## > my_seq <- c(my_seq, NA) # 加入一個 NA
## > mean(my_seq) # 輸出為 NA
## [1] NA
## > mean(my_seq, na.rm = TRUE) # 排除遺漏值
## [1] 3
1
2
3
4
5
6
7
8

描述統計函數:sd()

sd() 是能夠將輸入數值向量標準差回傳的函數,R 語言中的 sd() 函數定義為樣本標準差,在計算公式中分母使用的是 n — 1(Like var this uses denominator n — 1 。)

my_seq <- 1:5
sd(my_seq)
my_seq <- c(my_seq, NA) # 加入一個 NA
sd(my_seq) # 輸出為 NA
sd(my_seq, na.rm = TRUE) # 排除遺漏值
1
2
3
4
5
## > my_seq <- 1:5
## > sd(my_seq)
## [1] 1.581139
## > my_seq <- c(my_seq, NA) # 加入一個 NA
## > sd(my_seq) # 輸出為 NA
## [1] NA
## > sd(my_seq, na.rm = TRUE) # 排除遺漏值
## [1] 1.581139
1
2
3
4
5
6
7
8

描述統計函數:median()

median() 是能夠將輸入數值向量中位數回傳的函數。

my_seq <- 1:5
median(my_seq)
my_seq <- c(my_seq, NA) # 加入一個 NA
median(my_seq) # 輸出為 NA
median(my_seq, na.rm = TRUE) # 排除遺漏值
1
2
3
4
5
## > my_seq <- 1:5
## > median(my_seq)
## [1] 3
## > my_seq <- c(my_seq, NA) # 加入一個 NA
## > median(my_seq) # 輸出為 NA
## [1] NA
## > median(my_seq, na.rm = TRUE) # 排除遺漏值
## [1] 3
1
2
3
4
5
6
7
8

描述統計函數:range()

range() 是能夠將輸入數值向量中最大值與最小值回傳的函數。

my_seq <- 1:5
range(my_seq)
my_seq <- c(my_seq, NA) # 加入一個 NA
range(my_seq) # 輸出為 NA
range(my_seq, na.rm = TRUE) # 排除遺漏值
1
2
3
4
5
## > my_seq <- 1:5
## > range(my_seq)
## [1] 1 5
## > my_seq <- c(my_seq, NA) # 加入一個 NA
## > range(my_seq) # 輸出為 NA
## [1] NA NA
## > range(my_seq, na.rm = TRUE) # 排除遺漏值
## [1] 1 5
1
2
3
4
5
6
7
8

描述統計函數:sum()

sum() 是能夠將輸入數值向量中所有數值加總回傳的函數。

my_seq <- 1:5
sum(my_seq)
my_seq <- c(my_seq, NA) # 加入一個 NA
sum(my_seq) # 輸出為 NA
sum(my_seq, na.rm = TRUE) # 排除遺漏值
1
2
3
4
5
## > my_seq <- 1:5
## > sum(my_seq)
## [1] 15
## > my_seq <- c(my_seq, NA) # 加入一個 NA
## > sum(my_seq) # 輸出為 NA
## [1] NA
## > sum(my_seq, na.rm = TRUE) # 排除遺漏值
## [1] 15
1
2
3
4
5
6
7
8

描述統計函數:max()

max() 是能夠將輸入數值向量中最大值回傳的函數。

my_seq <- 1:5
max(my_seq)
my_seq <- c(my_seq, NA) # 加入一個 NA
max(my_seq) # 輸出為 NA
max(my_seq, na.rm = TRUE) # 排除遺漏值
1
2
3
4
5
## > my_seq <- 1:5
## > max(my_seq)
## [1] 5
## > my_seq <- c(my_seq, NA) # 加入一個 NA
## > max(my_seq) # 輸出為 NA
## [1] NA
## > max(my_seq, na.rm = TRUE) # 排除遺漏值
## [1] 5
1
2
3
4
5
6
7
8

描述統計函數:min()

min() 是能夠將輸入數值向量中最小值回傳的函數。

my_seq <- 1:5
min(my_seq)
my_seq <- c(my_seq, NA) # 加入一個 NA
min(my_seq) # 輸出為 NA
min(my_seq, na.rm = TRUE) # 排除遺漏值
1
2
3
4
5
## > my_seq <- 1:5
## > min(my_seq)
## [1] 1
## > my_seq <- c(my_seq, NA) # 加入一個 NA
## > min(my_seq) # 輸出為 NA
## [1] NA
## > min(my_seq, na.rm = TRUE) # 排除遺漏值
## [1] 1
1
2
3
4
5
6
7
8

小結

在這個小節中,我們簡介與示範 R 語言中常見的內建基礎函數,包含數值向量函數、文字向量函數與描述統計函數。

練習

  • R 語言有內建圓周率($$\pi$$),只要輸入 pi 就可以使用它,請練習使用 ceiling()floor()round() 函數將它轉換為 4、3 與 3.14
pi
ceiling(___)
floor(___)
round(___, digits = ___)
1
2
3
4
  • 請在 R 語言的命令列(console)用一段文字輸出今天的系統日期
today_char <- "Today is:"
sys_date <- Sys.Date()
paste(___, ___)
1
2
3
  • 我們有一個數值向量 num_vector ,請使用描述性統計幫我們計算它的總和與中位數
num_vector <- c(11:14, NA)
sum(___, na.rm = ___)
median(___, na.rm = ___)
1
2
3

延伸閱讀