緣由

近日工作有建立套件(package)的需求,參考了 Hilary ParkerWriting an R package from scratchFong Chun Chan’s BlogMaking Your First R Package 以及 Hadley WickhamR packages 後很快地就實作出來了。稍微找了一下繁體中文的教學,主要內容是使用 RStudio 來建立套件的方式,像 TW use-R五分鐘學會「如何使用Rstudio建立R套件 」,我認為整理一個精簡的繁體中文教學提供給喜歡操作 R 命令列指令的使用者應該是有價值的。

目標

如果你照著這篇文章走完,你將可以自行建立一個套件叫做 medianpack,安裝並載入這個套件之後,你可以使用 median_function() 函數來計算一組數值向量的中位數。當然 R 語言有內建的 median() 函數,如果不是為了展示自己建立套件,我們不需要自己寫一個。

步驟一:載入套件

建立一個套件我們得要倚賴兩個函數:

  • devtools::create()
  • roxygen2::roxygenize()

create()roxygenize() 這兩個函數分別源於 devtoolsroxygen2 套件,這兩個套件的作者也是 Hadley Wickham

packages_to_use <- c("devtools", "roxygen2")
install.packages(packages_to_use)
lapply(packages_to_use, library, character.only = TRUE)

步驟二:建立套件的架構

我們首先使用 create() 函數來建立套件的架構,它會在你目前的工作目錄(working directory)建立一個文件夾,這時要先想好套件的命名以及希望將它存放在哪裡,以我們的範例,是打算將套件放在 /~ 並且命名套件名稱為 medianpack

setwd("~") # 我們想將套件放在 /~ 的路徑下
create("medianpack") # 我們的套件名稱叫做 medianpack

執行完成之後,你會發現在你的 /~ 目錄底下已經多了一個 medianpack 資料夾,裡面有一些預先建立好的檔案與資料夾。

setwd("./medianpack") # 切換至套件資料夾下
dir() # 可以看到有三個檔案,一個資料夾
## [1] "DESCRIPTION"      "man"              "medianpack.Rproj"
## [4] "NAMESPACE"        "R"

步驟三:加入函數

~/medianpack/R 的路徑中創造一個 median_function.R

setwd("~/medianpack/R") # 切換至 ~/medianpack/R 資料夾下
file.create("median_function.R") # 建立一個檔案

並將一段簡單計算中位數的程式碼貼入:

median_function <- function(x) {
  x_sorted <- sort(x)
  if (length(x) %% 2 == 1) {
    return(x_sorted[(length(x) + 1) / 2])
  } else {
    return((x_sorted[length(x) / 2] + x_sorted[(length(x) / 2) + 1]) / 2)
  }
}

步驟四:建立函數文件

接下來我們要使用 roxygenize() 函數來為我們自製的 median_function() 建立文件,也就是你平時在 R 命令列輸入 ?欲查詢的函數 會跳出來的說明文件。在剛剛的 median_function.R 前面加入這個函數的基本資訊,所以你的函數看起來會長得像:

#' A Self-made Median Function
#'
#' This function allows you to calculate the median from a numeric vector.
#' @param x A numeric vector.
#' @keywords median
#' @export
#' @examples
#' median_function(seq(1:10))

median_function <- function(x) {
  x_sorted <- sort(x)
  if (length(x) %% 2 == 1) {
    return(x_sorted[(length(x) + 1) / 2])
  } else {
    return((x_sorted[length(x) / 2] + x_sorted[(length(x) / 2) + 1]) / 2)
  }
}

然後回到 ~/medianpack 底下執行 roxygenize() 函數。

setwd("~/medianpack")
roxygenize()

執行完後你會發現多出了一個資料夾 man,裡頭有 roxygenize() 函數自動產生出的 median_function.Rd.Rd 副檔名指的就是 R Documentation。

setwd("~/medianpack/man")
dir()
## [1] "median_function.Rd"

步驟五:測試

接下來我們把路徑移回到 /~ 使用 devtoolsinstall() 函數安裝 medianpack 套件,然後試用看看 median_function() 能不能被我們呼叫使用。

setwd("~")
## install("medianpack") # 這裡我們不使用 install.packages 因為我們的套件並沒有發佈到 CRAN
library(medianpack)
?median_function # 你可以在本機呼叫出剛才編寫的說明文件
median_function(seq(1:10))
## [1] 5.5

步驟六:從 GitHub 引入套件

當你撰寫了一個好用的套件,一定會迫不及待想跟你的工作團隊分享,最方便且最簡潔的分享方式是透過 GitHub 來引入你的自製套件,你可以使用 devtoolsinstall_github() 函數來完成。

## install_github("yaojenkuo/medianpack")
library(medianpack)
?median_function # 你可以在本機呼叫出剛才編寫的說明文件
median_function(seq(1:10))
## [1] 5.5

當然,如果你的套件上架到 cran 就更完美了。

下一步還可以學習什麼

這是關於建立套件的第一個簡單教學,你可以在 我的 GitHub 找到完整的程式碼與整個 medianpack 套件。建立套件還有更進階的應用像是如何在套件中引用其他的套件,以及在套件中包含資料供使用者載入後可以快速使用,像是你載入 nycflight13 之後就能馬上使用 flights 資料一樣。