kilometer’s

a junk space

[研究関連]  [R関連] [書評] [その他]

home


パッケージを作る

1. 準備: 使用するパッケージ

パッケージを作るための道具として{usethis}パッケージ、{devtools}パッケージ、{roxygen2}パッケージを用意します。どちらもCRANにあります。
この記事は以下のバージョンで書いています。

devtools_2.3.2  usethis_1.6.3 roxygen2_7.1.1

あとこの記事の中で{data.table}パッケージと{tibble}パッケージと{magrittr}パッケージが使われています。全てCRANにあります。

2. 準備:雛形を作る

RStudioのFile -> New Project… -> New Directory -> R Packageで、Package Nameを適当に設定してCreate Projectします。
「Create a git repository」をチェックするのも良いですね(お好みでどうぞ)。

3. 不要なファイルを消す

デフォルトで作られるR/hello.Rman/hello.Rdは、あってもいいですが、まあ格好悪いので消しておきましょう。

NAMESPACEというファイルもデフォルトで作成されます。これは自動作成に任せた方が楽ですので、次のコードを実行して自動更新の管理下に置きます。

usethis::use_namespace()

実行後にNAMESPACEファイルを開くと以下のように記述されているはずです。

# Generated by roxygen2: do not edit by hand

またヘッダーにThis document is read onlyと注意書きがポップしているはずです。これでOKです。

4. ソースコードを書く

新しいスクリプトを開いて(command + shift + N)、例えば、ラジアンと度を変換する関数を用意しましょう。

# degreeをradianに変換
radian <- function(degree){
  degree * pi / 180
}

# radianをdegreeに変換
degree <- function(radian){
  radian * 180 / pi
}
radian(180)
## [1] 3.141593
degree(pi/4)
## [1] 45

いい感じですね。これを適当な名前(例えばraddeg.R)で保存(command + S)します。自動的にプロジェクトの中のRフォルダに保存されることを確認してください。

はい、出来上がり!だと楽なんですがもう少しだけ手をかけます。

5. roxygenコメントを書く

これはまあ、こういうものとして覚えちゃうのが早いと思います。パッケージに使う関数にはそれぞれroxygenコメントを書きます。このコメントの書き方の御作法が正しく守られている必要があります。

#' Function to convert degree to radian
#' @param degree degree
#' @export
radian <- function(degree){
  degree * pi / 180
}

#' Function to convert degree to radian
#' @param radian radian
#' @export
degree <- function(radian){
  radian * 180 / pi
}
  • roxygenコメント通常のコメント#と区別するために#'で開始します。
  • 最初の行に関数の説明を1文で入れてください。
  • その下に関数に関する情報を@をつけながら記述します。
  • @paramは関数の引数に関する解説です。
  • @exportは関数をインストールしたユーザーが使えるようにしたい関数につけます。
  • パッケージ内部だけで使用される関数には@exportの記述は不要です。

6. ドキュメントを更新する

さて、それではこの2つの関数について必要なドキュメントを作成するようにRにお願いしましょう。

devtools::document()
Writing NAMESPACE
Writing radian.Rd
Writing degree.Rd

いい感じですね。

NAMESPACEファイルを開いてみると

export(degree)
export(radian)

となっているはずです。こうやって自動更新してくれるのは楽ちんですね。

7. DESCRIPTIONを更新する

まだやることがあるのか!
右下?のペインのFilesタブからクリックしてDESCRIPTIONファイルを開いてください。

いくつかの項目、Title, Author, Maintainer, Description, Licenseを埋めてください。適当でいいですが、あまりに適当だと怒られるので指定のフォーマットに従っておきましょう。

Package: sampleprj
Type: Package
Title: Sample package for demonstration
Version: 0.1.0
Author: kilometer
Maintainer: kilometer <kilometer0101@gmail.com>
Description: Sample package for demonstration.
License: CC0
Encoding: UTF-8
LazyData: true
RoxygenNote: 7.1.1

8. Check!

ここまできたらあと一息ですね。

左下?のEnvironmentのあるペインにあるBuildタブを開くと「Check」があるので押してみましょう。

0 errors ✔ | 0 warnings ✔ | 0 notes ✔

R CMD check succeeded

と表示されればOKです。

そのまま「Install and Restart」を押すと、コンソールが流れてlibrary(sampleprj)と読み込んでくれます。

> degree
function(radian){
  radian * 180 / pi
}
<bytecode: 0x7f7c5ca88400>
<environment: namespace:sampleprj>

いい感じ。

Build Source Packageとすると.tar.gzファイルを作ってくれるので配布に使えます。

もっと良いのはgithubでリポジトリを作って公開しちゃうことですね。

9. 関数を追加する

もう少し凝った関数を追加してみましょう。
パイプ演算子 %>% を使った関数を書いてみます。

#' Enter a vector and return a character vector of the elements with duplicates removed.
#' @param vector target vector
#' @export
#'
ext_levels <- function(vector){
  vector %>%
    unlist() %>%
    factor() %>%
    levels()
}

これを保存してCheckするとエラーになるはずです。%>%ってなんぞ?と言われてしまいます。

そういう時はパイプ使うよ!という宣言をしましょう。こんそコンソール上で以下を実行するだけでOKです。

usethis::use_pipe()
✔ Adding 'magrittr' to Imports field in DESCRIPTION
✔ Writing 'R/utils-pipe.R'
• Run `devtools::document()` to update 'NAMESPACE'

いい感じ。言われた通りドキュメントを更新します。

devtools::document()

で、もう一度Checkしてみてください。

他のパッケージの関数を使いたい場合はコメントに@importFrom pkj functionという形で記述しておきます。

#' Load the path using fread as a tibble
#' @importFrom data.table fread
#' @importFrom tibble as_tibble
#' @param path target path
#' @export
freadAstibble <- function(path){
  path %>%
    data.table::fread() %>%
    tibble::as_tibble()
}

これで

devtools::document()

とするとNAMESPACEファイルが次のような内容になっているはずです。

# Generated by roxygen2: do not edit by hand

export("%>%")
export(degree)
export(ext_levels)
export(freadAstibble)
export(radian)
importFrom(data.table,fread)
importFrom(magrittr,"%>%")
importFrom(tibble,as_tibble)

で、Check!

…するとエラーになるはずです。

❯ checking package dependencies ... ERROR
  Namespace dependencies not required: 'data.table', 'tibble'
  
  See section ‘The DESCRIPTION file’ in the ‘Writing R Extensions’
  manual.

1 error ✖ | 0 warnings ✔ | 0 notes ✔
 エラー: R CMD check found ERRORs
 実行が停止されました 

oh…

DESCRIPTIONファイルのImports項目に使いたいパッケージを記述しましょう。

Package: sampleprj
Type: Package
Title: Sample package for demonstration
Version: 0.1.0
Author: kilometer
Maintainer: kilometer <kilometer0101@gmail.com>
Description: Sample package for demonstration.
License: CC0
Encoding: UTF-8
LazyData: true
RoxygenNote: 7.1.1
Imports: 
    magrittr,
    data.table,
    tibble

これでCheckを通るはずです。改めてBuildしましょう。

……簡単ですね!!(ね!)

こうして出来上がったファイル群はgithubのここに置いてあります。



2022.06.02