最早接觸「函數」,可以追溯到國高中,y 與 x 的線性組合 y = f(x)。x 是 input(可以不只一個)、y 是 output,兩者之間用 f (function) 來作轉換與連結。在 R 裡,當我們想避免複製大量重複的程式碼(複製貼上程式碼超過 2 次)、讓其他使用者可以使用我們設計的函數,就可以用 f <- function(x){運算程式碼; return(y)} 進行自訂函數。
老師舉的例子,是創造包含 a, b, c, d 四個各自有 20 個標準常態分配亂數的變數,如果我們想把原本的尺度轉換到 0-1 之間,發現同樣的程式碼要寫四次:
df <- data.frame(
a = rnorm(20), # Generate 20 standard normal random numbers
b = rnorm(20),
c = rnorm(20),
d = rnorm(20)
)
df$a <- (df$a - min(df$a, na.rm = TRUE)) /
(max(df$a, na.rm = TRUE) - min(df$a, na.rm = TRUE))
df$b <- (df$b - min(df$b, na.rm = TRUE)) /
(max(df$b, na.rm = TRUE) - min(df$a, na.rm = TRUE))
df$c <- (df$c - min(df$c, na.rm = TRUE)) /
(max(df$c, na.rm = TRUE) - min(df$c, na.rm = TRUE))
df$d <- (df$d - min(df$d, na.rm = TRUE)) /
(max(df$d, na.rm = TRUE) - min(df$d, na.rm = TRUE))
但透過自訂函數,我們可以精簡地、用別人也很容易了解的方式,把重複操作的流程轉為必要程式碼,接下來只要帶入我們想要的變數即可:
RescaleByRange <- function(x){
rng <- range(x, na.rm = TRUE)
return((x - rng[1]) / (rng[2] - rng[1]))
}
我們可以比較兩者的結果是一樣的,但用自訂函數的方式,畫面變得簡潔多了!只是對新手如我,還是需要多做一點思考與複習,才能看懂、甚至是把邏輯轉換成程式碼,要寫出更有效率的函數還是要多練習。
> df$a <- (df$a - min(df$a, na.rm = TRUE)) /
+ (max(df$a, na.rm = TRUE) - min(df$a, na.rm = TRUE))
> df$a
[1] 0.6955101 0.6445714 0.3351554 0.1847988 0.3182214 0.5090866 0.5880603
[8] 0.9517401 0.1268596 0.4721010 0.6326112 0.6527196 1.0000000 0.4555521
[15] 0.5718586 0.3148169 0.1647536 0.6934324 0.6536277 0.0000000
> RescaleByRange(df$a)
[1] 0.6955101 0.6445714 0.3351554 0.1847988 0.3182214 0.5090866 0.5880603
[8] 0.9517401 0.1268596 0.4721010 0.6326112 0.6527196 1.0000000 0.4555521
[15] 0.5718586 0.3148169 0.1647536 0.6934324 0.6536277 0.0000000
練習題:撰寫一個名為 SummarizeData 的函數,回傳輸入向量的平均值 (mean)、變異數 (variance)、最大值 (maximum)、最小值 (minumum)、與中位數 (median)。
SummarizeData <- function(x){
# Computes the summary statistics of a vector.
#
# Args:
# x: the vector you want whose summary statistics is calculated.
#
# Returns:
# A data frame with the mean, variance, maximum, minumum, and median of x.
summary.df <- data.frame(x_mean = mean(x, na.rm = TRUE),
x_var = var(x, na.rm = TRUE),
x_max = max(x, na.rm = TRUE),
x_min = min(x, na.rm = TRUE),
x_median = median(x, na.rm = TRUE))
return(summary.df)
}
SummarizeData(rnorm(10))
附上手邊的幾個部落格和線上課程網址:
- Hahow 好學校 – R語言和商業分析-洞悉商業世界中的資料科學 [寫這些學習筆記歷程最主要的來源之一]
http://tinyurl.com/y2hhr3vf - 資料科學與R語言 [曾意儒老師 Yi-Ju Tseng]
https://yijutseng.github.io/DataScienceRBook/index.html - 統計計算與程式語言 [林建甫老師]
https://web.ntpu.edu.tw/~cflin/ - 認識 R 的美好 [郭耀仁老師]
https://bookdown.org/tonykuoyj/eloquentr/ - R系列筆記 [skydome20 老師]
https://rpubs.com/skydome20/Table