17 製本時のエラーへの対処

17.1 エラーがどのタイミングで発生したかを特定する

R Markdown はさまざまな外部プログラムを利用して, 数段階のプロセスを経てソースファイルを変換して文書を作成する複雑なプログラムである. 逆に言えば, Rmd ファイルを md ファイルに変換 (knitrによる処理) するときにエラーが出たのか (= R のプログラムにミスがある可能性が大), md を各ファイルに変換 pandoc する際に起こったのか (= 経験上ほとんどは tex ファイルのコンパイルエラーによるもの) をまず特定するのが重要である. そのためには

  1. keep_md: true / keep_tex: true を設定する
  2. うまくいかないときはキャッシュを削除してから再実行する

という対処法がある. (1) は文字通り中間出力ファイルである .md および .tex を残すことを意味する (tex ファイルの保全はデフォルトで true 設定になっている). これが生成されないなら knitr でのエラーだと分かるし, 中身を見て不自然な内容になっているのなら Rmd の書き方が knitr に正しく評価されていないことがわかる.

キャッシュも私の経験上よくエラーの原因となっている. 以前に実行していたチャンクの結果が更新されていないせいで, knitr の処理の不整合を起こすことがある. *_files には出力に必要な画像ファイルが, *_cache にはチャンク実行結果のキャッシュが残っている. 後者は knitr::opts_chunk$set(cache = T) などでキャッシュを残す設定にできるので, F に設定した上でこれらのファイルを削除する.

処理に時間がかかるチャンクがあってキャッシュを作りたい場合は, 別途 rdsRData ファイルに結果を保存するという方法もある. しかしもしプログラムの再現性を重視する場合, この方法は望ましくないだろう. しかし残念ながら現状はこうするか, ひたすら長い時間を待つしかない.

TODO: https://bookdown.org/yihui/rmarkdown-cookbook/cache.html

17.2 YAML フロントマターを確認する

以前『[R] R Markdown の YAML ヘッダでハマったおまえのための記事』というブログ記事にも書いたように, YAML フロントマターは慣れないと書き間違えやすいのが現状である. もし自分で変更したのなら, 改めて確認すべきだろう. 特に, 製本直後にすぐに, 心当たりのないRプログラム関係のエラーが出る場合, チャンクではなく YAML フロントマターの読み取りに失敗している可能性がある.

以下の4原則を覚えておこう. 以前は bookdown の話を想定してなかったので, さらに条文を1つ加えた.

  1. output: 以下はフォーマット関数への引数
  2. トップレベルのオプションは pandoc のオプション
  3. タイプミスや位置間違えでも動いたり, 動かなかったりする
  4. _output.yml および _bookdown.yml を見る.

output: には bookdown::gitbook など, bookdown で提供されているフォーマット関数を指定しており, その配下に記入するのはフォーマット関数に与える引数である. よって, 関数ヘルプを確認すれば有効な引数を知ることができる. しかし一方で, ... が引数になっていることがあるので, タイプミスしてもエラーが出ないことがある.

また, YAMLの構文でサポートされている配列は誤評価を引き起こすことがある.

output:
  bookdown::gitbook:
    toc_depth: 3
    toc: true
output:
  bookdown::gitbook:
    - toc_depth: 3
    - toc: true

上の例は正しい記法である. 一方でハイフン - は YAML では配列を記述するために用意されている. 下記の場合, キーワード引数ではなく位置引数のような扱いになるため, toc に対して 3 を代入することになり, エラーが発生する. 逆に言えば, - を使う場合, キーワードを書かずに値だけを正しい順番で書けば機能する.

インデントしないトップレベルの引数は, 基本的に pandoc に与える引数である. これ意味のない引数を与えてもエラーを返さないことが多いので, タイプミスに注意する.

しかし, フォーマット関数に pandoc_args という構文をサポートしていることや, フォーマット関数で pandoc の同名の引数を上書きする仕様のフォーマットもあるため, 上記は絶対ではない. これが原因で, 「output: 以下に書くべきものを間違えてトップレベルに書いたが, 意図したとおりに機能した」あるいはその逆が発生することがある. また, pandoc の構文ではキーワードにハイフンを使うことができるが, フォーマットは R の関数でもあるためハイフンを使えず, アンダースコアで置き換えられる. この違いも書き間違えの原因になる.

17.3 PDF 生成時のエラーを確認する

それでもエラーが出る場合, 私の経験上ほとんどが生成した .tex ファイルをタイプセットする際にエラーが発生している. html との両立を考えると, どうしても pandoc が解釈できる構文に限界がくるためである.

! LaTeX Error: XXXXX

とか

Error: LaTeX failed to XXXX

といったメッセージが表示されるのですぐ分かる. さらに丁寧なことに, tinytex のデバッグ方法へのリンクまで表示される

この場合最も重要なのは, 以下に尽きる.

  1. options(tinytex.verbose = TRUE) を設定する
  2. keep_tex: true を設定する

これは keep_md と同様に, 中間ファイルである .tex を残すことを意味する.

それでも解決しない場合, 改めてこのファイルを手動でタイプセットするのも1つの方法だ. もしうまくいったり, 異なるエラーが出るのなら, 環境の違いが問題かもしれない. そして upBibTeX を使うのなら, 後者が唯一のデバッグ方法だ.

17.4 よくあるエラーメッセージ

17.4.1 The File XXX.Rmd Exists.

The file _main.Rmd exists. Please delete it if it was automatically generated. If you are sure it can be safely overwritten or deleted, please set the option 'delete_merged_file' to true in _bookdown.yml.

多くの場合はファイル名が _main.Rmd となるだろう. つまり最終的に出力する PDF と同じ名前である. これは _bookdown.ymlbook_filename で変更することができる. このエラーは文字通り _main.Rmd ファイルが既に存在するから処理を続行できない, というものである. 製本時に index.Rmd と同じフォルダに, 中間生成物である _main.Rmd が作られるが, 前回の製本処理が何らかの理由でエラーが発生し中断しているとこのファイルが残ることがある. よってこのファイルを削除すれば解決する.

17.4.2 No Site Generator Found.

製本処理にあたって, 基準となるフォルダの設定が見つけられない際に発生する. index.Rmdsite: bookdown::bookdown_site が記述されていないか, ビルドペーンでの設定でフォルダを正しく設定できておらず, index.Rmd の存在しないフォルダを参照していることがよくある原因である.