R Markdownで楽々レポートづくり

第3回レポつく自由自在~R Markdown基礎文法最速マスター

はじめに

前回までの記事でシンプルなレポートの作成方法はわかってもらえたと思います。ですが、文章ベタ書きのレポートでは読み人に親切とは言えません。見出しや箇条書きなど、わかりやすい文章構造でレポートを記述する必要があります。また、デフォルトの設定では、グラフのサイズが小さすぎる、レポートにコードが表示されている、などなど、あなたが思い描く理想のレポートには程遠いと感じるかもしれません。

R Markdownには、そんなあなたの要望を叶えてくれる機能が盛りだくさんです。例えばドキュメント部分で見出しやリスト、表を使いたい、グラフを大きく表示したい、結果だけ見せてコード部分はレポートに表示したくない、コストの掛かる処理をキャッシュして効率化したい、といったことが簡単に実現できます。

そこで今回と次回はR Markdownの文法として、ドキュメント部分の体裁を整えるためのMarkdown記法、コードチャンクの処理を制御するためのチャンクオプション、レポート出力を制御するためのパッケージオプション、R Markdownファイルの分割と統合、レポートのメタ情報の設定方法など、レポートづくりを更に効率化して、レポートの体裁をより良く整える方法について説明します。

なお、今回のタイトルは御存知の通り基礎文法最速マスターに倣ったものです。今まで内緒にしていましたが、この中のR 基礎文法最速マスターを作成したのは実は筆者です。いい加減な仕事ぶりが著者の人柄をよく表していますね。

Markdown記法

Markdownとはシンプルなテキストによって文書構造を記述するための軽量マークアップ言語です。記述が簡単なHTMLのようなものだと思ってもらえばいいでしょうか。見出し(ヘッダ⁠⁠、箇条書きリスト、番号付きリスト、テキスト修飾、表、画像、ハイパーリンクなどを簡単な記法で表現できます。マークダウンにはいくつか方言がありますが、R Markdownでは文書の変換にpandocを使っているので、pandoc拡張マークダウンでドキュメントを記述します。

ここではレポート作りに役立つ記法を抜粋して紹介します。既にMarkdown記法に精通している方は読み飛ばしてください。

段落

ただの改行はスペースに変換されます。空白行が段落区切りになります。強制改行したい場合は、行末に半角スペースを2つ続けます(下の例では「そ」の後ろに半角スペース2つが入っています⁠⁠。

あいうえお
かきくけこ

さしすせそ  
たちつてと

あいうえお かきくけこ

さしすせそ
たちつてと

見出し(ヘッダ)

行頭に#(シャープと半角スペース)でヘッダです。#を重ねることで最大レベル6ヘッダまで指定できます。

# レベル1ヘッダ
## レベル2ヘッダ

リスト

行頭に*で箇条書きリスト、行頭に1.などで順序付きリストです。行頭に4つの半角スペースを入れることで入れ子もできます。

* ビール
* ワイン
    * 白ワイン
    * 赤ワイン
* 日本酒

1. 食べる 
1. 飲む
    1. 酔う
    1. 寝る
1. 太る

(HTMLでは)次のように出力されます。

  • ビール
  • ワイン
    • 白ワイン
    • 赤ワイン
  • 日本酒
  1. 食べる
  2. 飲む
    1. 酔う
    2. 寝る
  3. 太る

水平線

レポートの見た目を整えるのに、水平線はワリと便利です。3つ以上の-(ハイフン)です。

---

テキスト修飾

文字列を記号で囲むことで就職修飾できます。

これは*強調*でこれは**強い強調**でこれは~~とりけし~~でこれは`文字通りの出力`で上付き下付きη_p_^10^など。

これは強調でこれは強い強調でこれはとりけしでこれは文字通りの出力で上付き下付きηp2など。

表はレポートに有効ですね。いくつかの記法があります。ここではパイプテーブルを紹介します。

|種類|価格|度数|意識の高さ|
|----|----|----|---|
|ビール|程々|程々|程々|
|ワイン|ピンきり|高め|高め|
|日本酒|ピンきり|高め|高め|
種類 価格 度数 意識の高さ
ビール 程々 程々 程々
ワイン ピンきり 高め 高め
日本酒 ピンきり 高め 高め

画像・ハイパーリンク

ハイパーリンクは[テキスト](リンクアドレス)という形式です。

R Markdownの公式サイトは[こちら](http://rmarkdown.rstudio.com/)です。

R Markdownの公式サイトはこちらです。

画像の挿入は![画像タイトル](アドレス "alt属性")という形式です。

![gihyo.jpのロゴ](http://image.gihyo.co.jp/assets/templates/gihyojp2007/image/gihyojp_logo.png "gihyo.jpのロゴです")
gihyo.jpのロゴ
gihyo.jpのロゴ

引用

行頭に>で引用ブロックです。引用ブロック中で改行するには行末に2つの半角スペースをおきます。

> ここは引用に
> なります。  
> 次の行です。

(HTMLでは)次のように出力されます。

ここは引用に なります。
次の行です。

他にも数式やコードブロックなどがあります。 さらに知りたい方はpandoc拡張マークダウンを参考にしてください。

コードチャンクの処理の制御

R Markdownファイルの基本形は次の通りです。

---
title: "タイトル"
author: "作成者"
date: "作成日"
output: html_document
---

```{r setup, include=FALSE}
# セットアップチャンク
# パッケージのロード、データ読み込みなど、Rオプション設定など
library(foo)
options(width = 1000)
dat = read.table("hoge")
knitr::opts_chunk$set(echo=FALSE) # 全てのコードチャンクに適用されるオプション
```

```{r analysis, include=FALSE}
# 解析コード
```

マークダウンテキスト ・・・

```{r table-head, echo=TRUE}
# 表の出力
knitr::kable(head(iris))
```

マークダウンテキスト ・・・

```{r plot-head, fig.width=5, fig.height=3}
# グラフの出力
plot(haed(iris))
```

マークダウンテキスト ・・・

一番上の---で囲まれた部分はYAMLフロントマターと呼ばれるもので、レポートのメタ情報を指定したり、出力フォーマットを指定したりします。YAMLフロントマターは省略しても構いません。この場合はデフォルトの設定でHTMLレポートが出力されます。YAMLフロントマターについては次回詳しく説明します。

セットアップチャンク

YAMLフロントマターの後に、マークダウン記法によるテキスト、セットアップを行うコード、解析コード、グラフや表出力のRコードなどが続きます。

Rのコードはコードチャンクに記述します。上の例では最初に、

```{r setup, include=FALSE}
# セットアップチャンク
# パッケージのロード、データ読み込みなど、Rオプション設定など
library(foo)
options(width = 1000)
dat = read.table("hoge")
knitr::opts_chunk$set(echo=FALSE) # 全てのコードチャンクに適用されるオプション
```

というセットアップチャンクを置いています。ここではパッケージの読み込みやRのオプション設定、その他、レポート内のコード全般に関する設定などを行います。セットアップチャンクは必須ではありませんが、R Markdown全体の見通しが良くなるのでオススメです。

チャンクラベル

コードチャンクの書式は次のようなものです。

```{r plot-one-to-ten, fig.width=3, fig.height=3, echo=FALSE}
# コード
plot(1:10)
```

コードチャンクのヘッダ行ではチャンクラベルを指定できます。上の例ではplot-one-to-tenがチャンクラベルです。チャンクラベルは、そのチャンクにより出力されるグラフのファイル名、キャッシュ時のファイル名、チャンクコードの再利用時のラベル指定など、色々な用途に使われます。ラベルを指定しなければ暗黙的にラベル名が設定されますが、特に長くてややこしいレポートを作成するときなどはチャンクラベルを明示的に指定しておくとよいでしょう。

チャンクオプション

チャンクラベルに続けて、オプション名=値という形でチャンクオプションを指定できます。上の例では、fig.width=3, fig.height=3, echo=FALSEとして3種類のオプションを指定しています。チャンクオプションによって、そのチャンクについての処理を細かく制御できます。例えば出力するグラフのサイズを変更する、コードの表示・非表示を設定する、結果の出力の方法を変更するといったことが可能です。

チャンクオプションの一括指定

knitr::opts_chunk$set(echo=FALSE)

のようにすることで、このチャンクより後の全てのチャンクに同じオプションを適用できます。opts_chunk$set()により指定したチャンクオプションは、チャンクヘッダ行でのオプション指定により上書きされるので、R Markdownの先頭のほう(例えばセットアップチャンク)でデフォルトの動作を一括指定しておいて、デフォルト以外の動作をさせたいチャンクでは、チャンクヘッダで指定する、といったことが可能です。

よくできていますね。

使えるチャンクオプションランキング

今回の記事は少し固めの内容だったので、ここからは趣向を変えて、レポートづくりに苦労しているひなさんとR Markdownエキスパートの玲さんの姉妹二人の会話形式で、レポートづくりに使えるチャンクオプションを抜粋して紹介します。チャンクオプション神7と呼ばれているとかいないとか。

これ以外にもたくさんのオプションがありますので、公式サイト(英語)ドキュメント生成本匿名知的集団ホクソエムのお笑い担当teramonagiさんによるまとめ記事などを参考にしてください。

第7位:child

ひな パパに頼まれたデータ解析、超ややこしすぎて、このR Markdownファイルすでに1000行オーバー。編集したい場所を探すだけでも一苦労よ。これでごほうびヤクルト1本って、どんだけブラックなのよ。

  確かにブラックよね。わたしにもそんな時代があったわ~。でもね、そんな時は解析コードを別のR Markdownファイルに書いておいて、childオプションを指定すればいいのよ。

ひな どゆこと??

  まずc01.Rmdとかc02.RmdとかのR Markdownに解析コードを書くのね。本当は解析の内容がわかるようなファイル名をつけとくといいわ。で、チャンクオプションでchild="c01.Rmd"とかすれば、そのコードチャンクの内容がc01.Rmd`で置き換えられるのよ。実際に使ってみるといいわ。

```{r c01, fig.width=8}
# 子となるR Markdown(c01.Rmd)
plot(1:10)
```
```{r c02}
# 子となるR Markdown(c02.Rmd)
knitr::kable(head(iris))
```
親となるR Markdownparent.Rmd

# プロット

```{r child="c01.Rmd"}
```

# テーブル

```{r child="c02.Rmd"}
```

  こういうレポートができるわ。

ひな なにこれ、このR Markdown超見やすくなってるじゃない!! これならどんだけややこしい解析コードでもR Markdownの編集の邪魔にならないわ~。Cの#includeみたいなもんね。

第6位:opts.label

ひな あー、もうイヤ~

  ?

ひな このレポート、同じオプションのコードチャンクがいっぱいあるんだけど、いちいち書くの超めんど~。これならワードの方がマシ!!

  それは確かに面倒ね。オプション一括指定じゃダメなの?

ひな それがダメなのよ~、大きいグラフと小さいグラフがたくさんあるから、チャンクごとに指定しないといけないの。

  そんなときにはチャンクオプションテンプレートの出番よ。

ひな なにそれ~

  いい? まずセットアップチャンクとかで、テンプレートを定義するの。

```{r setup, include=FALSE}
library(knitr)
opts_template$set(
  fig_small = list(out.width = 200, out.height = 200), # 小さいグラフ
  fig_large = list(out.width = 500, out.height = 500)  # 大きいグラフ
  )
```

ひな それからそれから~?

  それから、コードチャンクではopts.labelオプションでテンプレート名を指定するのよ。

```{r fig1, opts.label="fig_small"}
curve(sin(x),-10,10)
```

```{r fig2, opts.label="fig_large"}
plot(iris)
```

```{r fig3, opts.label="fig_small"}
curve(cos(x),-10,10)
```

ひな 簡単ね!

  そうでしょ~。そして、これがサンプル出力よ!! どう?

ひな すごい! これなら何回も書かなくてすむわ~。あ、あと、私気づいちゃったんだけど、テンプレートを使えば、グラフの大きさ変えたいときはセットアップチャンクの値を変えるだけでいいんじゃないの、これ?

  よく気づいたね~。だから間違いも起こりにくくなるし、どんだけ手間省けるんだこれ、って感じよね。Cの#defineマクロみたいなものよ。

第5位:warningerrormessage

ひな パッケージ読み込むとたまにメッセージ表示されることあるじゃない。レポートにマジ邪魔なんですけど~

  そんなときはmessage=FALSEよ。

ひな 瞬殺ね……

  warning=FALSEなら警告が非表示よ。あと、error=TRUEならそのチャンクのエラーを出力して、その後のチャンクは実行されるの。error=FALSEならエラー時点で変換処理が止まるわ。デフォルトは全部TRUEよ。

第4位:fig.widthfig.heightout.widthout.height

ひな なにこれグラフちっさ!!

  あ~ほんとだ、これじゃ、パパ、キレるわ~

ひな レポートのグラフ大きくするの、どうしたらいいの?

  out.widthout.heightでレポートのグラフの大きさを指定できるわよ。このオプションの単位は、レポートのフォーマットによって異なるわ。HTMLのレポートならピクセル。out.width=800, out.height=800とかすれば800ピクセル四方の領域にグラフが拡大縮小されて表示されるっていうこと。PDFのレポートならLaTeXの単位が使えるわ。out.width=".8\\linewidth"とかね。あなたLaTeX知ってる?

ひな もちろん! 毎晩、絵本がわりに美文書6版眺めてるの!

  美文書には私もお世話になったわ、5版だったけど。これ、ほんとに役に立つわよね。あれ? この本、技術評論社なのね~さすがだわ~

ひな ところでおねえちゃん、fig.widthout.widthってなんか違うの?

  fig.widthfig.heightはグラフを描画する画像ファイルとかPDFファイルのサイズを指定するのよ。単位はインチ。例えばHTMLレポートを作る場合、fig.width=4, dpi=150なら、幅600ピクセルのPNGファイルがこっそりできるの。dpiはdot per inchの略で、1インチあたりのピクセル数ね。で、このファイルがout.widthout.heightで指定された領域に拡大縮小されて表示されるってわけ。要するに、fig.widthfig.heightはRがグラフを作成するときのサイズ、out.widthout.heightはHTMLとかPDFに出力するときのサイズだと思っておけばいいわ。サンプルおいておくわね。わかりにくくてゴメンね~

ひな 大丈夫、完璧。R Markdownってホントにカユいところに手が届くッて感じだわ。作者、きっとモテるわね。

  それな

第3位:cache

ひな ビーッグ ビッグビッグ ビッグデータッ♫

  陽気ね……

ひな 違うわよ~、気が狂いそうなの。データが巨大すぎて、解析に超時間かかるのね。で、テキストとかグラフの見た目とか修正してrender()のたびに解析してるから、どんだけ時間かかるのよこれ、ッて感じだわ。これならワードのほうがマシ!!

  ありがちね、気持ちわわかるわ。そんなときのために、キャッシュよ。

ひな え、R Markdownってキャッシュまでサポートしてるの?

  あなた、キャッシュ理解してるの? やるわね。cache=TRUEのチャンクはキャッシュされるから、そのチャンクに変更がなければ2度目からはコードは実行されないわ。

ひな つまり、超時間節約ってことね。でもね、解析チャンクの中で作ったオブジェクトを後のチャンクで結果表示のために使ってるのよ。だから実行されないと困るの。

  と思うでしょ? でも大丈夫。cache=TRUEのチャンクで作られたオブジェクトはこっそりとファイルに保存されてるの。で、そのあとのチャンクでは、オブジェクトをこっそりファイルからロードしてくれるのよ。だから、本当は実行されないけど、実行されると思い込んで大丈夫よ~

ひな なにこれ捗るわ~

  キャッシュについては次回もう少し詳しく説明するかも。楽しみにしててね!

第2位:echo

ひな コードチャンクのコードって、レポートにいらなくない? 別に解析コードを見せたいわけじゃないし……

  つecho=FALSE

ひな m(_ _)m

第1位:include

ひな おねえちゃんのR Markdown、色んな所でinclude=FALSEってあるけど、なんなのこれ?

  これはわたしのナンバーワンオプション、⁠レポートに載せない」よ。

ひな 載せない? どういうこと?

  include=FALSEにしたチャンクは、レポートの中から存在抹消よ。でも安心してね、コードは実行されるわ。

ひな なるほど、よく考えるとそ~ゆ~チャンクってたくさんあるわ。セットアップチャンクでしょ、下処理チャンクに~、あと解析チャンクも結果を出力しないならレポートにはいらないわね。

  そうよ。でもこのオプション、あんまり有名じゃない気がするわ。わたしはプ◯キュアよりもinclude=FALSEが好きなのに。

ひな へ~そうなんだ~。便利なのにね~。おねえちゃん、今日はありがとう!! お礼にわたしのヤクルト半分わけてあげる~

まとめ

今回紹介したように、R Markdownは自分の作業ルーチンに合わせて自動処理の振る舞いを細かく制御できます。使い込めば使い込むほど、その便利さが実感できることでしょう。

気がつけばもう6月です。暦の上ではもう夏。そろそろ近所のビアガーデンも動き出した頃ではないでしょうか。R Markdownを駆使してさっさと仕事を片付けて、ビアガーデンに繰り出しましょう!

Enjoy!!

次回は

次回はレポート出力を制御するためのパッケージオプション、R Markdownファイルの分割と統合、レポートのメタ情報の設定方法など、レポートづくりをさらに効率化するためのノウハウを紹介します。また、今回も入稿したオリジナルの原稿である、自動変換処理などを行う前のR Markdownファイルやサンプルなどをまとめて公開しておきます。

おすすめ記事

記事・ニュース一覧