fusen とは

RMarkdown ファイルから R パッケージを生成するパッケージ。

公式ドキュメント: Build a Package from Rmarkdown File • fusen

利点

  • RMarkdown さえ書ければパッケージが作れる。
  • 関数の定義・例・テスト・vignette をまとめて一つの場所で書くことができる。
  • まずドキュメンテーションから始める “Rmd ファースト” なパッケージ開発スタイルを実現できる。

Rmd の例

例えば次のような形で関数の定義、例、テストを書くことができる

# ベクトルの中央値を計算する

```{r function}
#' 中央値の計算
#'
#' @param x 数値ベクトル
#' @inheritParams stats::median
#'
#' @return
#' ベクトル x の中央値
#' @export
#'
#' @examples
my_median <- function(x, na.rm = TRUE) {
  if (!is.numeric(x)) {stop("x は数値型である必要があります")}
  stats::median(x, na.rm = na.rm)
}
```

```{r examples}
my_median(1:12)
```

```{r tests}
test_that("my_median が正しく動作し、必要なときにはエラーが発生すること", {
  expect_true(my_median(1:12) == 6.5)
  expect_error(my_median("text"))
})
```

使い方

インストール

開発の流れ

  • 新規ディレクトリ/プロジェクトの作成
    • RStudio テンプレートを使う場合、File > New Project > New directory > Package using {fusen} を選択する
      • テンプレートの選択
        • 最初は fusen の動作を理解するため teaching を選択
        • 2回目は様々な疑問への答えが書かれている full を選択
    • コマンドラインを使う場合、create_fusen("path/to/new/project", template = "teaching") を実行する。
  • パッケージのセットアップを開始するため、“dev/flat_teaching.Rmd” を開く
  • この flat テンプレートファイルで、最初の description という名前のチャンクでパッケージの説明やライセンスを聞かれるので、その内容を編集して実行する。
    • このコードは次のような形になる:
fill_description(fields = list(Title = "My Awesome Package"))
usethis::use_mit_license("Sébastien Rochette")
  • この Rmd テンプレートの残りの部分で、分析コードやパッケージの機能を書く
    • 開発時には使用例やテストを書くこともできる。
    • 最初はコードを編集せずそのままにしておいても動作するパッケージになっている。
  • 次のコードを実行して フラットな Rmd ファイルを変換し、パッケージへとふくらませる
    • このとき、生成された vignette が開く。
fusen::inflate(
  flat_file = "dev/flat_teaching.Rmd",
  vignette_name = "Get started",
  check = TRUE
)

これだけでパッケージが作成されている。

今度は作成したパッケージをテストする:

  • 作成したパッケージをローカルにインストールする。
remotes::install_local()
  • 環境をクリアするため、R セッションを再起動する
    • RStudio セッションを再起動すれば “Build” タブが表示されるようになる
  • 開発したパッケージの関数を使ってみる
my.package::my_median(1:12)
  • このパッケージの専用サイトをビルドして、ドキュメンテーションが正しいかテストする
# {pkgdown} でサイトをビルドしてみる
usethis::use_pkgdown()
pkgdown::build_site()
# > references や articles を見てみる

fusen::inflate() で生成されたファイル vignette/get-started.Rmd は、 pkgdown によってこのサイト上のページ articles/get-started.html に変換される。

コードチャンクの命名規則

  • function という名前のコードチャンクは関数定義のコードになる。
  • example という名前のコードチャンクはその関数の例になる。このコードは関数の @examplesroxygen2 のコメント)となり、また vignette の一部としても残る。
    • チャンク名はユニークにする必要があるので、必要なら番号をつけて example-1, example-2, … のようにする。
  • tests という名前のコードチャンクは単体テストのコードとなる。
  • development という名前のコードチャンクは開発目的で使用される。usethis の関数など、通常は1回だけ実行される。

制約

  • 1つの関数につき1つのタイトル・1つの function チャンクを書く。
  • examplestests チャンクは関連する function チャンクの直後に置く。
  • function チャンクにサブ関数を書くこともできる。同じチャンクの関数は同じ R ファイルに書き込まれるが、サブ関数は @examples を持つことができない。examples は最初の関数だけに反映される。
  • Rmarkdown ファイルの制約として、チャンク名はユニークになっている必要がある。そのため、番号をつけて examples-1, examples-2, … のように区別する。
  • グローバル環境で定義された関数が影響するのを避けるため、ワークスペースは常にクリーンな状態に保つこと。

感想

  • fusen::inflate() を実行したとき、デフォルトでは R CMD check が実行される。
    • LaTeX が入っていないときや、日本語が交じっているときにエラーが出る。
    • 時間が掛かる。
  • => カジュアルに使うなら無理せず check = FALSE で良いと思う。
  • テストの実行は devtools::test() で行う。
fusen::inflate(
  flat_file = "dev/flat_full.Rmd",
  vignette_name = "Get started",
  check = FALSE
)
devtools::test()