初めてのR Markdownテンプレート作成法

この記事は,ベイズ塾 Advent Calendar 2020 - Adventar14日目の記事です。

R Markdownって本当に便利ですよね。Rコード,結果,文章を統合してHTMLやPDFに出力してくれます。コピペすることで生じるミスもなくなります。ベイズ塾では,@kazutanの影響もあり,随分と前からR Markdownが使われてきました。

R Markdownでは,投稿する雑誌や用途に合わせて作られたテンプレートが配布されており,内容だけに集中してフォーマット調整をする場合に便利です。今回は,既存のRMarkdownテンプレートで飽きたらなくなった方に向けた記事になります。

今回は,WordやHTML出力はスルーして,PDF出力に限定した内容です。PDFに限定する理由は,HTMLで厳密にフォーマット調整することはあまりなさそうですし,Wordの場合は,最終的にはWordで調整すれば良い気がするからです。投稿できる形式に整えられた論文をPDF出力するような状況を想定しています。

R Markdownテンプレートパッケージの例

作り方の解説の前に,私が作ったR Markdownテンプレートパッケージを紹介します。どちらも日本語を使用した論文PDFテンプレートになります(なので,日本語を処理するための工夫を色々しています)。どちらもインストールするとR Markdownの新規作成時のフォーマットとして選択できるようになります。

まず,勤務先の専修大学人間科学部心理学科の卒論用R Markdownテンプレートです。GitHubも一緒に活用すると卒論指導の手間が半分になり,楽しさが2倍になりました*1。中身を埋めていって,Knitすると学科で指定しているフォーマットで卒論のPDFが出力されます。卒論用なので教育目的の内容がテンプレート内のコメントとして入っています。

github.com

次に,日本心理学会の発行する『心理学研究』用R Markdownテンプレートです。海外の雑誌のR Markdownテンプレートは充実してきたのですが,日本語を使うような国内誌のR Markdownテンプレートはほとんどないので作成しました。こっちはプロ用なので,あまり教育目的のコメントは入っていません。

github.com

RMarkdownテンプレート作成に有用なサイト

では,R Markdownテンプレート開発をはじめましょう。最初にテンプレート開発に使えるサイトを紹介します。

まず,本家の「R Markdown Cookbook」です。これが全てといえます。

bookdown.org

次に,Kazutanが以前にまとめた,「R Markdownの内部とテンプレート開発」です。ただ読むだけだと分からないのですが,実際にテンプレートを作り始めると,かゆいところに手が届く情報がまとまっています。

kz-md.net

この2つの資料を軸にしつつ,あとはグーグル検索でR Markdown, LaTeXあたりの情報を得ていく感じになります(私はライトユーザーなのでPandocについてはほとんど調べないです。この程度でも,雰囲気でなんとかなります)。

R Markdownテンプレート用Rパッケージの作成方法

それでは,R Markdownテンプレート用Rパッケージを作ってみましょう!基本的にはRのパッケージと同じなのですが,テンプレートファイルを配置したり,出力時の設定用R関数を書くあたりが特殊かもしれません。

(1)R Markdownの設定を変更して出力を調整する

R Markdownでは,一番上のYAMLを変更することで,LaTeXパッケージを追加したりできます。ただ設定が増えていくと大変ですし,細かい調整は難しくなるので,texのテンプレートファイルを作って,以下のように指定することもできます。

output:
  pdf_document:
    template: my-template.tex

一般的には,以下のdefault.latexというテンプレートに変更を加えてTeXテンプレートを作ります。以下のdefault.latexをみると分かりますが,$$でくくられた記法を使っています。細かい話をするとR Markdownでは,knitでMarkdown形式に変換して,それをPandocなるものを使ってLaTeX経由でPDF出力をします。そのPandocでLaTeX形式にする際に,TeXテンプレートを使います(よく分かんなけど,たくさんの人の支えによってR MarkdownからPDFが出力されているのだけは分かります)。

pandoc/default.latex at master · jgm/pandoc · GitHub

default.latexテンプレートを修正したものでもいいですし,何か理想とする出力に近いTeXテンプレートを元にして,それに修正を加えるのも良いかと思います。まあ,出力したい形式で出力できるTeXテンプレートを作るのが一番大変なところです。ただ,私はいつも試行錯誤をして,ほぼ雰囲気で書いたり修正しているので,まだ上手に言語化できません。なので,今回は省略します(とりあえず,やりたい内容×TeXもしくは内容×R Markdownで検索して,出てきた方法をTeXテンプレートに落とし込んでいる感じです)。以降は,TeXテンプレートとR Markdownテンプレートができた状態として進めます。

(2)Rパッケージ作成の下準備をする

以下の記事の「(5) 一旦コミットして,GitHubにプッシュする」まで作成します。

cpp-laboratory.hatenablog.com

(3)R Markdownテンプレートの作成

ここからがR Markdownテンプレート用の設定です。通常のRパッケージでは,Rフォルダ内に関数を定義したファイルを配置します。R Markdownテンプレートでは,inst > rmarkdown > templates > テンプレート名のフォルダを作り(つまり,inst/rmarkdown/templates/テンプレート名のフォルダ/),その中にファイルを配置します。inst/rmarkdown/templates/テンプレート名のフォルダ/を作りましょう。

次に,テンプレート名のフォルダ内にtemplete.yamlを作ります(つまり,inst/rmarkdown/templetes/テンプレート名のフォルダ/templete.yamlを作る)。senshuRmdの場合は,以下のような感じです。

f:id:cpp-laboratory:20201213143708p:plain

YAML内にR Markdownテンプレートの説明などを書きます。以下は,senshuRmdの内容です。nameに書かれた内容が,R Markdownファイルをテンプレートから作ろうとするときの名前になります。Rmdファイル以外のファイルも配布する場合は,create_dir: trueにしておきます。

name: Thesis format for Senshu
description: Thesis format for Department of Psychology, Senshu University
create_dir: true

そして,テンプレート名のフォルダ内にskeletonフォルダを作って,skeleton.Rmdを含む配布するファイルを配置します(つまり,inst/rmarkdown/templates/テンプレート名のフォルダ/skeleton/skeleton.Rmdを作る)。skeleton.Rmdは,R markdownのテンプレートです。senshuRmdの場合は,以下のように,参考になるように,fig1.pngやbibファイルなども配置しています。

f:id:cpp-laboratory:20201213143915p:plain

なお,senshuRmdのskeleton.RmdのYAMLは以下のようになっています。重要なのは一番最後の行で,output:でPDF形式や特定のテンプレートを指定するのではなく,senshuRmd内のsenshu_thesis関数を使っています(後述しますが,この関数で出力などの設定をしています)。

title: 'タイトル:'
author: '学籍番号: 氏名:'

bibliography:  reference.bib
suppress-bibliography: yes
output: senshuRmd::senshu_thesis

最後に,テンプレート名のフォルダ内にresourcesフォルダを作って,TeXテンプレートファイルを配置します(つまり,inst/rmarkdown/templetes/テンプレート名/resources/texテンプレート.tex)。senshuRmdの場合は,以下のようになります。

f:id:cpp-laboratory:20201213143920p:plain

(4)R Markdownテンプレート用R関数の作成

続いて,skeleton.RmdのYAMLにおいて,outputに指定した関数を設定します。関数の設定は以下の通りになります。ご自身のテンプレートに合わせて,関数名,テンプレート名,パッケージ名を変更ください。

#' 説明
#' @export
関数名 <- function(){
  template_tex_file <- system.file("rmarkdown/templates/テンプレート名/resources/テンプレート名.tex",
    package = 'パッケージ名')
  format_pdf <- rmarkdown::pdf_document(latex_engine = "xelatex",
    template = template_tex_file,
    keep_tex = TRUE,
    toc = TRUE,
    toc_depth = 3,
    highlight = 'tango')
  format_pdf$inherits <- "pdf_document"
  format_pdf
}

ちょっと説明をすると,system.file()でテンプレートを読み込んでいます。rmarkdown::pdf_documentでPDF出力の設定をしますが,日本語を使う場合は,xelatexを使います。

Rパッケージを完成させる

devtools::check()を使ってビルド&チェックしつつRパッケージとして完成させます(詳しくは, 初めてのRパッケージ作成:最初の一歩 - Computational Clinical Psychology Lab を参照ください)。

完成したら,GitHub経由でインストールして,File -> New File -> R Markdown...をクリックします。

f:id:cpp-laboratory:20201213154728p:plain

New R MarkdownでFrom Templateを選ぶと,自作したR Markdownテンプレートが出てくるので,選択して,OKをクリックします。

f:id:cpp-laboratory:20201213154732p:plain

後は,執筆・解析して,knitすれば理想のフォーマットのPDFが生成されます!

Enjoy!

*1:卒論執筆じゃなくて卒論指導です。とはいえ今後の社会人生活における共同作業の方法を身につけるという意味では教育効果も高いのではないかなと思います?