Windows 環境下での PDF 生成で日本語文字を問題なく扱える R Markdown 設定

R Markdown の処理環境は 2015年9月現在、英語マニュアル等を参考に素直にセットアップしただけの状態では、Windows で日本語を含んだ R Markdown を書いて PDF 出力すると、文字の化けや行あふれが処置されないなどの現象が発生してしまいます。

これらを解決する設定を [テンプレートとして使えるファイル] (https://raw.githubusercontent.com/naqtn/rmarkdownJa/master/inst/rmarkdown/templates/ja_pdf_article/skeleton/skeleton.Rmd) にまとめてみたので紹介します。（あわせて PDF と HTML を同じ R Markdown ファイルから作り出すときに問題が起きない対策もほどこしました。）

この記事の後半では対処している問題とファイルの記述内容について解説します。



# 前提 TeX 環境

R Markdown 形式から PDF を得るには TeX 形式を扱う環境が必要です。TeX 環境を整備する手段はいくつかありますが、MikTeX ディストリビューションを使用することにします。

準備として http://miktex.org/download から Net Installer を入手し、全パッケージ（Complete）をダウンロードしてデフォルトインストールします。2G弱のダウンロードが必要で多少時間はかかりますが、設定に特段の知識は必要ありません。（補足：基本部分のみの Basic でも良さそうなのですがエラーに遭遇してしまいます（2015/9/27 時点）。ただこれは一時的な MikTeX の不具合かもしれません。）



# 設定サンプルファイル

設定内容は [こちらのファイル] (https://raw.githubusercontent.com/naqtn/rmarkdownJa/master/inst/rmarkdown/templates/ja_pdf_article/skeleton/skeleton.Rmd) にまとめました。このファイルは先頭部分に必要な設定記述がされていて、後半は出力例示になっているので適宜削ってご利用ください。ヘッダ直後の部分に書き換えに最低限必要な情報をコメントの形で書いておきました。

また、同じ内容を R Studio の ファイル新規作成時のテンプレートとして取り込むようにしたパッケージも作成してみました。詳しくは https://github.com/naqtn/rmarkdownJa/blob/master/README.md にて。

注意：設定中フォント名として Meiryo が指定されています。このまま Windows 外の環境へ持っていくと問題が起きるので注意してください。

---

以降は設定内容の解説です。ファイルを使うだけであれば読む必要はありません。

---

# 解説

（論文調のである体にスイッチします。）

「Windows で、日本語を、PDF へ出力」で起きる問題について対処をネット検索すると多く情報は得られるのだが、断片的だったり、情報が古かったり、不完全だったりするものが多く少々苦労した。まとまった情報が見当たらないのでまとめてみることにした。

設定方法は、現時点で最もシンプルで妥当だと思われる次の３つの記事の内容をベースにすることにした。（miyazakikenji さん、ありがとうございます。）

* [knitrで日本語のはいった作図] (https://miyazakikenji.wordpress.com/2014/01/12/knitr%E3%81%A7%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%AE%E3%81%AF%E3%81%84%E3%81%A3%E3%81%9F%E4%BD%9C%E5%9B%B3/)
* [RStudio で簡単に日本語 PDF](https://miyazakikenji.wordpress.com/2015/02/15/rstudio-%E3%81%A7%E7%B0%A1%E5%8D%98%E3%81%AB%E6%97%A5%E6%9C%AC%E8%AA%9E-pdf/)
* [R Markdown に日本語pdf](https://miyazakikenji.wordpress.com/2015/08/14/r-markdown-%E3%81%AB%E6%97%A5%E6%9C%AC%E8%AA%9Epdf/)

これをベースとして

* フォント指定をチャンクのデフォルトオプションで与えるように
* プロット（グラフ描画）における文字コード変換の Warning を綺麗に消すように
* 日本語文用の TeX 文書クラス（BXJS）を使用するように
* 出力先を HTML にしても（YAML ヘッダ以外の）書き換えの必要が無いように

という改善を加えた。

以降では、これらの問題の背景を説明し、今回紹介している設定ファイルでどのように扱っているかを簡単に解説する。なお R Markdown と LaTeX の基礎的な概念と記述方法については前提知識とする。（少し噛み砕いて書こうとも思ったが、とても長くなる予感で挫折。）


（私は TeX にふれるのは十数年ぶり＆ R Markdown と R は初学者レベルのため、間違ったことを書いているかもしれません。その節はもしよろしければご指摘ください。）


## TeX の日本語文組版指定を整える

### TeX ディストリビューションの選択

R Studio は TeX 環境をセットアップせずに R Markdown から PDF 作成を行うと

        Windows: MiKTeX (Complete) - http://miktex.org/2.9/setup
        (NOTE: Be sure to download the Complete rather than Basic installation)

と MiKTeX (Complete) の使用がうながされる。日本国内では他のディストリビューションの方が優勢であるようだが、ここでは設定項目が増えることを嫌って R Studio 側の都合を優先させて MikTeX を採用することにした。

オプションパッケージの要不用に悩むのは面倒なので、うながされるまま Complete インストールを行った。（繰り返しになるが補足：全パッケージ でなく Basic をインストールして必要なものを追加でも良さそうだが、2015/9/27 現在試したところエラーに遭遇してしまう。ただしこれは一時的な MikTeX の不具合かもしれない。）

（MiKTeX は日本語文の処理の都合で [お勧めしない]( http://oku.edu.mie-u.ac.jp/~okumura/texwiki/?MiKTeX ) 向きもあるようだが、後述する BXJS 文書クラス（[BXjscls パッケージ](http://oku.edu.mie-u.ac.jp/~okumura/texwiki/?BXjscls)）の登場により実用上は問題無いようである。横書きに関しては「[pTeX 並の品質](http://oku.edu.mie-u.ac.jp/~okumura/texwiki/?XeTeX)」とのこと。）



### TeX エンジンの選択

rmarkdown パッケージが組み込みでサポートしている TeX エンジンは pdfLaTeX, XeLaTeX, LuaLaTeX である。pdfLaTeX は rmarkdown パッケージでのデフォルトである。開発は事実上止まっていて安定している。XeLaTeX は開発は続いているようだが、ほぼ安定している模様。LuaLaTeX はまだベータ版のみの段階である。（現在の R Studio で LuaLaTeX は設定項目 UI にあらわれない。）

日本語を処理するには pdfLaTeX は不十分であるらしいこと、LuaLaTeX はまだ安定感が無いので（とはいえ具体的な問題が見られるわけではないが）、XeLaTeX を第一選択にした。その上で LuaLaTeX での動作も確認する方針を取ることにする。

（参考：XeLaTeX と LuaLaTeX の比較参考 [LyX wiki | LyX / XeTeX](http://wiki.lyx.org/LyX/XeTeX) 日本国外の視点として参考になる。）



### 日本語組版のための BXJS 文書クラス

PDF 出力の際、デフォルトのまま文書クラスを指定しないと内部的には article が使用され日本語としての組版が行われず、長い行が用紙をはみ出るといったような事が起こる。2015/9 現在 XeLaTeX で日本語組版をするには BXjscls パッケージの BXJS 文書クラスを使用するのが便利である。BXjscls について詳細は次を参照。

* http://oku.edu.mie-u.ac.jp/~okumura/texwiki/?BXjscls
* https://github.com/zr-tex8r/BXjscls
* https://github.com/zr-tex8r/BXjscls/raw/master/bxjscls-manual.pdf

日本語組版の指定方法は他にもあるが BXjscls を使うと YAML ヘッダの記述量を少なくでき、また TeX エンジンを変更した時の変更点も少なくなる、これをベースに利用する。


### YAML ヘッダに記述

以上の選定により YAML ヘッダは次のようになる。

        output:
          pdf_document:
            latex_engine: xelatex
          beamer_presentation:
            pandoc_args:
            - --latex-engine
            - xelatex
        documentclass: bxjsarticle
        classoption: xelatex,ja=standard
        geometry: no

<!-- ------------------- -->

documentclass には以下のいずれかを指定する。（BXjscls パッケージ で提供されている BXJS 文書クラスのいずれか）

* bxjsarticle ： 章のないレポート
* bxjsreport ： 章のあるレポート
* bxjsbook ： 書籍
* bxjsslide ： スライド （使用可だが beamer_presentation を使ったほうが良いだろう）

classoption にはフォントサイズ、用紙サイズ、landscape などのパラメータを指定可能。詳細は BXjscls のドキュメントを参照。

* http://oku.edu.mie-u.ac.jp/~okumura/texwiki/?BXjscls
* https://github.com/zr-tex8r/BXjscls/raw/master/bxjscls-manual.pdf


YAML ヘッダで geometry は使用できない。no を指定しておくこと。（BXjscls が内部的に使うため。上記マニュアルを参照。）

TeX エンジンに LuaLaTeX を使いたい場合には３箇所の xelatex との部分を lualatex にする。

<!-- ------------------- -->

なお bxjsarticle は分割して書くと bx-j-s-article で次のような意味になる。

* LaTeX の、記事や論説文のための article を、
* 日本語対応させたのが jarticle で、
* それを改良した「新ドキュメントクラス」jsarticle というのがあって、
* それを Unicode 化した最近の TeX エンジンで使えるようにしたのが bxjsarticle

beamer_presentation においても TeX を使用するので設定を記載した。（エンジンの指定表記法が現在は pdf_document と異なるので注意。これは同じ latex_engine にしてほしいものだ。）

geometry の行は書かなくても動作するが、原因をつかめていないものの誤動作する場合があるようなので no を明示した。

以上の記述により、R Markdown 本文中の日本語は適切に扱われるようになる。



## グラフ中の日本語の文字化け（トーフ化）対策

グラフ中の軸のラベルなどに日本語文字列を指定するとデフォルトでは文字化け（トーフ化）する。これはデフォルト使用されるフォントが日本語グリフを含んでおらず、表示が白四角（トーフ）になってしまう問題である。日本の R 界隈では以前からよく知られている現象で、対処としてフック機構を使い各自の .Rprofile で

     setHook(packageEvent("grDevices", "onLoad"), function(...) grDevices::pdf.options(family="Japan1"))

とする方法などが使われてきたようだ。（参考 R [日本語化掲示板](http://www.okadajp.org/RWiki/?%E6%97%A5%E6%9C%AC%E8%AA%9E%E5%8C%96%E6%8E%B2%E7%A4%BA%E6%9D%BF) ）

R Markdown ではチャンクオプションでオプション設定を明示的に与えられる。しかしチャンク毎に同じ事を書くのは記述の手間やメンテナンスの観点から好ましくないので、デフォルト値を与えられる knitr::opts_chunk を使用するようにした。

加えて、一つの R Markdown ファイルから PDF と HTML や Microsoft Word 形式を出力しようとする場合、固定的にデバイス指定していると具合が悪い。（MS Word では図を PDF にすると正常表示されない。MS Word では png が適当だろう。一方 PDF で png では品質が悪い。）そこでこれを出力先形式が latex の時のみこのデフォルト設定が動作するようにした。（ソース中 `knitr::opts_knit$get("rmarkdown.pandoc.to")` の部分。knitr の段階では最終出力先が TeX なのか PDF なのかは区別なく latex となっているようだ。区別つく方法もあるのかもしれないが。）


### （副問題）グラフ描画デバイスの選択

TeX 出力で使用するのに適したデバイス指定には pdf と cairo_pdf がある。このデバイスの選択には一長一短があるようなので利用者にゆだねる事にして、サンプルでは両方を書いたうえで一方をコメントアウトすることにした。

（フォントを指定する family の指定値は両者で異なり、 cairo_pdf では OS のフォント名を指定し、pdf ではあらかじめ決められた `Japan1` などの抽象的な名称を使う。cairo_pdf の方が PDF へのフォント埋め込みがされて機能的には都合が良いが、指定方法が処理系依存になってしまう。配布状態ではフォント埋め込み問題の方を優先させて cairo_pdf を有効な状態にしてある。）



## プロットにおける文字コード変換の Warning 対策

何も対策しない状態では、グラフの描画で日本語文字列を指定すると

    Warning: conversion failure on '（文字化け文字列）' in 'mbcsToSbcs': dot substituted for <（16進数表記１バイト）>

という警告が発生し、生成した PDF にこのメッセージがあらわれてしまう。この問題は Windows のみで発生する。

対処としてチャンクのオプション指定 warning=FALSE で握りつぶす方法を示しているページが多くある。しかしそれでは自分が書いた R コードで本当に warning を出した時にそれに気づけなくなってしまうので不適切である。（これを何とかしたかったのが、このまとめを作るに到った動機でした。）

調査したところ解決方法は knitr 作者のサイトのグラフィックス機能についての解説部分 http://yihui.name/knitr/demo/graphics/ の Encoding of multibyte characters の節に記されていた。ただこの部分だけでは不明瞭で詳細は https://github.com/yihui/knitr/issues/436 を見る必要がある。
options 関数で device を設定し、さらに別途にチャンクのオプションでも dev 指定をせよ、とのことである。

[knitr の Graphics Manual](https://github.com/yihui/knitr/releases/download/doc/knitr-graphics.pdf) knitr は二回デバイスをドライブする。（なぜこうなっているかははっきり書いていないが、プロットの記録を読み直して配置調整するなどするためらしい。）そして問題の warning は二回目の PDF ファイル生成時ではなく、最初のドライブでデフォルトの dev="pdf" が使われその内部で発生しているようである。よってこれを cairo_pdf することで warning 発生を抑止することにした。（chunk オプションの dev は二回目のものであり、これだけを cairo_pdf にしても問題は発生する。）


### （参考）pdf デバイスの実装調査

根本原因はデフォルトの pdf デバイスの実装に有りそうだが不明である。

R のソース中 `src/library/grDevices/src/devPS.c` を軽く見たが、エンコードの取り回しが難解で挫折した。（R の実装内部は多くの言語処理系が発展の過程で経験した Laten ⇒ プラットフォーム依存  ⇒ Unicode の過程を歩んでいる最中らしい。）条件を変えて現象を観察した感じでは native エンコードである CP932 と UTF-8 をどこかで取り違いをしているようだ。warning に表れるコードは UTF-8 になっている。UTF-8 を CP932 と思い込んでコンバートできないとの waning を発生しているように見える。

Linux や MacOS ではこの問題に遭遇しないらしい。これらシステムでは OS の locale で UTF-8 が指定された状況で稼動しているのが通常なため（native が UTF-8 になるため）、不具合が発現しないのではないかと予想する。



# おまけ（Tips、問題、課題）

この課題を調査するなかで知った Tips や問題を記載しておく。

## R Studio の R Markdown 編集部分のメニューの振る舞い（下向き三角形のプルダウン部分）

現在の R Studio (ver 0.99.484) では、R Markdown 編集部分の所に「Knit PDF」などのボタンがあり GUI から手軽に出力形式を得られるようになっている。その右には三角形のプルダウンがあり、変換先形式が選べる。

ここは少し奇妙な動きをしていて、選択肢が YAML ヘッダに書かれる output の先頭子要素に影響されるようだ。レポート文書系（HTML, PDF, Word）のいずれかが先頭だと同じレポート文書系のみがメニューにあらわれ、プレゼンテーション系（ioslides, Slidy, Beamer）のいずれかが先頭だとプレゼンテーション系がメニューにあらわれる模様だ。しかもメニューの選択により R Studio が YAML ヘッダを書き換えてくる。

（サンプルファイルでは、行の入れ替えだけで行き来ができるように output に現在標準で使える全ての形式を載せた。）


## 表題をグラフではなく本文側に書く（キャプション）

グラフの表題をグラフ描画側ではなく本文側につける方法もある（科学論文ではそれが普通らしい）。その場合は YAML ヘッダで

        fig_caption: yes

とした上で、チャンクの方で次のように指定する。

        ```{r, fig.cap="キャプション文字列" }
        plot(cars)
        ```


## Date を現在時刻にする

YAML ヘッダ項目に日付を与える `date` があるが、これは次のようにすると R Markdown を処理した時点の値に出来る。

        date: "`r format(Sys.time(), '%Y/%m/%d')`"


## pch に文字が指定できる

`plot(cars, pch="車")` のように pch には文字が指定できる。`pch="\u2603"` などのように Unicode文字での指定も出来る。当然ながら使用するフォントがサポートしていないと表示されないが。 [ネタ元](http://www.okadajp.org/RWiki/?%E6%97%A5%E6%9C%AC%E8%AA%9E%E5%8C%96%E6%8E%B2%E7%A4%BA%E6%9D%BF#yde074c8)

## 問題が起きた時に中間ファイルを得て原因を探る

YAML ヘッダで `keep_tex: yes` としておくと PDF 出力処理の中間段階の TeX ファイルと個々のグラフの PDF （ないしは画像）が残る。

## （未調査） Display equation が MS Word で通らない

本文中にドル記号を二つ重ねて書く独立した行を作る数式表現が、出力先を Microsoft Word にした場合にフォーマットされず元の表記のままになってしまう。（これは PDF 出力の問題ではないが、R Markdown の Windows 活用というより広いテーマでは関連するので記載しておく。）

## （未解決）フォント指定の環境依存性はなんとかならんか？

配布状態の設定では、生成 PDF が埋め込みフォントになって問題を起こさないことを優先し、cairo_pdf を使うことにした。cairo_pdf では論理名でなく OS でのフォント名を指定するので、環境依存性が生じている。cairo_pdf をやめて pdf にすればフォント指定は `family="Japan1"` と環境非依存にできるが、生成 PDF にフォントが埋め込まれず非日本語環境に持って行くと問題が起きるだろう。

追加の R Package を利用して良いのであれば独自 output 形式を定義して、そこのコードに環境依存性を押し込んで、使用するフォントを動的に与えるようにはできるだろう。しかしそれはそれで、各OSの実フォント名とどう結びつけるか問題が残るし、R Studio のお手軽な Knit 先切り替え操作が使えなくなってしまう。

R Markdown を流通させたい環境が身の回りの固定であるのならば、例えば IPAフォントをそれぞれの OS の機能でインストールして共通に使うというのが簡単な解ではありそうだ。