色々なテーブルを並べたレポートを大量生産したい
R Advent Calendar 2021 15日目の記事です。
https://qiita.com/advent-calendar/2021/rlang
今年の春ぐらいから半年ほどかけて、R用Dockerイメージとしてよく使われるrocker/rstudio
やrocker/tidyverse
などをビルドしているrocker-org/rocker-versioned2
リポジトリのビルドシステム改修作業を行っていました(Japan.R 2021のショートセッションで話しました)。
その作業の一環で、ビルドされたDockerイメージの情報をレポートとして記録するよう機能を作ろうというという話になり、R Markdownでやってみたら簡単だったので簡単に紹介します。
このような実際に動いている実例があると理解しやすくなると思いますので、参考にしてみてください。
(このリポジトリでイメージの更新のある度に動いて、毎回100以上のMarkdownファイルを生成しリポジトリ付属wikiに登録しています)
なおill-identifiedさん(@s_katagiri)の最近訳された、R Markdown Cookbookに非常にお世話になりました。「こんなことやりたいけどできるのかな?」と思ったらこの本の中を探して見ることをオススメします。
R Markdown クックブック:https://gedevan-aleksizde.github.io/rmarkdown-cookbook/
R Markdown Cookbook 原著(英語):https://bookdown.org/yihui/rmarkdown-cookbook/
実例
↓のテンプレートから
↓みたいなレポートや
https://github.com/rocker-org/rocker-versioned2/wiki/r-ver_7967f4e91da7
↓みたいなレポートが出力されました。(GitHub Actionsによる自動生成)
https://github.com/rocker-org/rocker-versioned2/wiki/ml-verse-cuda11_6e34075afb48
読み込む外部ファイルのパスを外部から指定する
yamlヘッダーのparams.<parameter_name>
で変数を設定し、rmarkdown::render(params = list(<parameter_name> = parameter))
という感じで外部から変数の中身を設定できます。
変数の中身はparams$parameter
という感じで取り出せます。
以下の例ではタイトルをimage_name
という変数で指定し、それ以外に5つのファイルのパスを変数で指定するようになっています。
title: "`r params$image_name`"
params:
image_name: ""
inspect_file: ""
imagetotls_inspect_file: ""
apt_file: ""
r_file: ""
pip_file: ""
レポート内では、以下のようにparams
からファイルのパスを読み込んで加工してテーブルを出力しています。
inspect_file
にはdocker instpect image <imagename>
コマンドで出力させた、Dockerイメージの情報の書き込まれたjsonファイルを指定するので、これでDockerイメージの情報をレポート内に読み込めるわけです。
df_inspect <- jsonlite::read_json(params$inspect_file)
クックブックではここに書かれています。
https://gedevan-aleksizde.github.io/rmarkdown-cookbook/parameterized-reports.html
ルートディレクトリをプロジェクトのルートディレクトリに合わせる
RMarkdownファイルを実行するとき、デフォルトではルートディレクトリはRMarkdownファイルのある場所に設定されます。
これだと外部ファイルを読み込む際の相対パス指定がややこしかったりするので、{rprojroot}
パッケージの関数を使ってプロジェクトのルートディレクトリをルートディレクトリに変更してやると便利かもしれません。
以下のようになチャンクを書いてやると、knitするとき(rmarkdown::render()
を実行しRMarkdownファイルから最終的なレポートを出力させるとき)のルートディレクトリを変更してやれます。
```{r, include=FALSE}
knitr::opts_knit$set(root.dir = rprojroot::find_root_file(criterion = rprojroot::is_git_root))
```
(Qiitaではバッククオート4つで囲ってもバッククオート3つのコードブロックをコードとして認識させられないのでスペース4つで認識させています。上記ブロック左側のスペースはそのためのものなので無視してください)
これはknitするときに使用される設定なので、RStudioでRMarkdownファイルを編集中にチャンクを実行して内容を確認するとき用には別途Global Optionsで設定が必要です。
vscode-Rの場合はそもそもRMarkdown用にルートディレクトリを変更するような機能は持っていないため気にする必要はありません。(と言うかこの設定をやらないと書きづらい)
ワーキングディレクトリについてはクックブックのこのあたりに書かれています。{rprojroot}
パッケージについては触れられていないので、別途{rprojroot}
パッケージのドキュメントを確認してみて下さい。
https://gedevan-aleksizde.github.io/rmarkdown-cookbook/working-directory.html