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

第5回レポートを彩るデータ可視化 ~グラフとテーブルとダイアグラム~

データを扱うレポートには、グラフやテーブルなど、データの可視化が不可欠です。今回は特にR MarkdownでHTML形式のレポートを作成する時に役立つ可視化手法について紹介します(PDFレポートなどでも使える手法もあります⁠⁠。可視化においてもコピペ汚染の排除、再現性の確保、すなわちオートメーション化が最重要課題であることに変わりはありません。今回紹介する手法は全て、外部グラフ作成ツールやテーブル作成ツールなどを使うこと無く、.Rmdファイルの中で完結できるようになっています。

なお、それぞれの手法についての詳細な解説は避けて、どのようなことができるのかを広く浅く紹介します。というのも、レポートを作る際には自分が使う手法をきちんと使えれば充分で、全ての手法に精通している必要はないからです(誌面が足りないというのと執筆時間が足りないというのもあります⁠⁠。今回の記事を一通り眺めてもらって、R Markdownでどのような可視化が利用できるのかをなんとなく認識してください。そして、自分が使いたいと思った可視化手法については、さらに突っ込んで学習してみるとよいでしょう。

JavaScriptを使った可視化などは現在でもアクティブに開発が進められていて、充分な日本語リファレンスが存在しない場合もあります。質問など、コメント欄またはツイッター @kohskeまで気軽にどうぞ。また、tokyo.Rの有志によるGitHubベースの気軽なQ&Aサイト「Rワカラング」というものが、最近開設されたようです。チャットルーム要メールアドレス登録も準備されたようです。是非活用してください。

グラフを極める

前回までの記事で紹介しているように、R Markdownでグラフを扱うのはとても簡単です。プロット関数を記述すれば、出力されるグラフを自動的にレポートに埋め込んでくれます。ggplot2パッケージのグラフ出力などでも問題なく利用できます。

なおチャンクオプションfig.capによってグラフのキャプションを指定することができます。この場合、YAMLヘッダでfig_caption: trueを指定することが必要です。

---
output:
  html_document:
    fig_caption : true
---

正弦波です。

```{r fig.cap="図1: 正弦波", echo=FALSE}
curve(sin(x), -10, 10)
```

サンプル出力はこちらです。

また、グラフの大きさは本連載第3回の記事で紹介したfig.widthなどのチャンクオプションで指定します。

rglパッケージによるインタラクティブな3Dグラフ

多次元データを可視化したい時など、XY軸だけのグラフでは物足りない場合があります。このような時には3Dグラフを使うとよいでしょう。ちなみに3Dグラフというのは、無意味に奥行きがついて立体になったグラフのことではなく、XYZの3軸をもつグラフのことです。

Rでは{rgl}パッケージによって視点変換が可能なインタラクティブな3Dグラフを簡単に作成できます。さらにHTMLレポートではWebGLというOpenGLをブラウザ上で表示する技術により、{rgl}で作成したグラフをレポートに埋め込むことができます。

{rgl}のグラフを埋め込むには、前回紹介したフックを使います。フック関数は組み込みで提供されているので、まず、knit_hooks$set(webgl = hook_webgl)としてフック関数を登録して、チャンクオプションでwebgl=TRUEとしてフックを有効にします。

```{r setup, include=FALSE}
library(knitr)
library(rgl)
knit_hooks$set(webgl = hook_webgl)
```

# irisの3D可視化

グリグリできるよ〜〜

```{r, webgl=TRUE, echo=FALSE}
plot3d(iris[1:3], col=rainbow(3)[iris[[5]]])
```

サンプル出力はこちらです。

JavaScriptライブラリを用いたインタラクティブなグラフ

JavaScriptは暗黒の時代を乗り越え、いまやWebにおけるスターダム技術です。可視化分野でも、D3.jsを中心として、JavaScriptのパワーをフルに活かした各種ライブラリが開発されています。一方、RでもこれらのJavaScriptライブラリを簡単に扱うためのパッケージが多数リリースされています。これらのパッケージを使うと、R Markdownで作成するHTMLレポートの中にJavaScriptライブラリによる可視化データを埋め込むことができます。

JavaScriptライブラリによる可視化のメリットとして、グラフをインタラクティブに操作できるという点が挙げられます。例えば一部ズームする、データの値をツールチップで表示する、などなど、とても強力で柔軟なデータ表現が可能です。ただ絵として描かれたグラフを貼り付けるという従来のレポートの概念を覆すものです。

ここではdygraphsライブラリを使うための{dygraphs}パッケージを紹介します。

# 時系列の可視化

表示幅など、インタラクティブに操作できます。

```{r, echo=FALSE}
library(dygraphs)
lungDeaths <- cbind(mdeaths, fdeaths)

dygraph(lungDeaths) %>%
  dySeries("mdeaths", label = "Male") %>%
  dySeries("fdeaths", label = "Female") %>%
  dyOptions(stackedGraph = TRUE) %>%
  dyRangeSelector(height = 20)
```

サンプル出力はこちらです。是非グラフを操作してみてください。

RとJavaScriptを用いた可視化技術は現在、急速に進歩しています。JavaScript可視化を行うためのパッケージのリストや、各パッケージの使い方がまとめられたリソースは今のところ見当たりません。興味がある方はリクエストを送ってもらえば、⁠R+JavaScriptによる可視化」みたいな連載が企画されるかもしれません。

テーブルを極める

グラフは視覚に強く訴えるインパクトのある可視化技術ですが、正確な数値を把握する用途には向きません。一方、テーブル(表)はグラフとは逆に、地味ですが正確な数値を示すのに最適な可視化技術です(テーブルを「可視化」と呼ぶのは異論もあるかもしれませんが⁠⁠。

突然ですが、問題です。あなたはレポートの中でテーブルを使いたいとき、どうやってテーブルを作りますか?

  1. Excel
  2. エクセル
  3. ゑくせる
  4. その他

1から3を選んだあなたは間違いなくコピペ汚染されていますね。そんなあなたは連載第1回を読み直してください。

R Markdownのアプローチでは、データから自動的にテーブルを作成してレポートに埋め込みます。{knitr}パッケージのkable()関数を使うのが一番簡単な方法でしょう。

# irisの先頭

```{r, echo=FALSE}
knitr::kable(head(iris))
```

次のようなテーブルが出力されます編集部注⁠。

Sepal.Length Sepal.Width Petal.Length Petal.Width Species
5.1 3.5 1.4 0.2 setosa
4.9 3.0 1.4 0.2 setosa
4.7 3.2 1.3 0.2 setosa
4.6 3.1 1.5 0.2 setosa
5.0 3.6 1.4 0.2 setosa
5.4 3.9 1.7 0.4 setosa
編集部注)
gihyo.jpのスタイルシートを当ててあります。

たった、たったこれだけで、テーブルをレポートに埋め込むことができるのです。 しかもコピペ汚染もなく、再現性も確保できます。データが更新されても、値をコピペしてテーブルを作って、レポートにまたコピペ、という作業は必要ありません。

kable()以外にも、より柔軟なテーブルの作成をサポートする{tables}パッケージがあります。ドキュメント生成本で詳しく解説されていますので参考にしてください。

JavaScriptライブラリを用いたインタラクティブなテーブル

テーブルは正確に数値を把握できる反面、データが大きい場合に見づらい、必要な数値を探すのが大変、といったデメリットもあります。さて、どうしましょう?

ここで再びJavaScriptです。HTMLレポートでは、テーブル表示を行うJavaScriptライブラリを使うことができます。何がスゴイって、なんと、レポートの中でテーブルのソートや検索ができるのです。従来のレポートでは考えられないことです。

ここではDataTablesライブラリを使うための{DT}パッケージを紹介します。mtcarsデータをテーブルで表示してみましょう。

```{r, echo=FALSE}
library(DT)
datatable(mtcars)
```

これだけです。これだけで、こちらのようなテーブルがレポートに埋め込まれます。

なんということでしょう。Searchと書かれた検索ボックスはただの飾りではありません。試しにMazdaと入力してみてください。フィルタリングです。テーブルヘッダをクリックしてみてください。ソートです。これは感動モノですね。

「レポートで、感動を」

アクセスログを整形してレポートで提出する時、実験データをフルで求められた時、レポートの中にテーブルが必要な時は、是非JavaScriptベースのテーブル作成を試してみましょう。そこには利便性とともに、感動があります。

ダイアグラムを極める

グラフとテーブル以外に、レポートで用いる可視化手法としてダイアグラム(フローチャート)があります。Rでダイアグラムを作成するには{Rgraphiz}{diagram}(こちらは第1回で利用しました)などを使うことができます。

最近になって、{DiagrammeR}パッケージというJavaScriptライブラリを使ったダイアグラム作成パッケージの開発が進められています。ちなみに開発者はイケメンです。

{DiagrammeR}を使えば、HTMLレポートに簡単な記述でダイアグラムを埋め込むことができます。日本語を扱う場合は、grViz()関数でgraphvizベースのダイアグラムを書くのがよいでしょう。記法は基本的にgraphvizの書式に従っています。

```{r echo=FALSE}
library(DiagrammeR)
grViz('
digraph {
  rankdir=LR
  node [shape = box,
        style = rounded,
        fontname = Helvetica]

  太る [shape = egg]
  食べる -> 飲む
  飲む -> 飲む
  飲む -> 酔う
  飲む -> 寝る
  酔う -> 太る
  寝る -> 太る
}
')
```

サンプル出力はこちらです。

この手のフローチャートであれば「パワポでおk」という意見もあるでしょうし、それは否定しません。ですが、データからダイアグラムを作成するような場合は、コピペ汚染を避けるためにも、やはりオートメーション化を検討するべきでしょう。{DiagrammeR}では、エッジとノードをdata.frameで定義してダイアグラムを作成することもできます。データドリブンのダイアグラムの場合はこちらの方がよいでしょう。以下に一例を示します。

```{r}
library(DiagrammeR)
set.seed(23)

library(rvest)
h = html("https://twitter.com/teramonagi/lists/list/members")
L = h %>% html_nodes(xpath="//*/div/div/div/a/strong") %>% html_text()

n = create_nodes(nodes = L)
e = create_edges(from = sample(L, replace = TRUE),
               to = sample(L, replace = TRUE))
g =
  create_graph(nodes_df = n,
               edges_df = e,
               graph_attrs = "layout = twopi",
               node_attrs = c("fontname = Helvetica"))

render_graph(g)
```

サンプル出力はこちらです。

このように、ノードとエッジからなるグラフオブジェクトを可視化することもできます。この例では、⁠匿名知的集団ホクソエム」という謎のTwitterリストのユーザをrvestを使って取得して、ダイアグラムを作成しています。今回はエッジはランダムに割り当てていますが、実際の解析ジョブでは例えばタイムラインからメンションを取得して、ユーザ同士の関係を可視化するといったことなどがありそうです。この場合、⁠パワポでおk」とはいきませんよね。

{DiagrammeR}ではこれ以外にもガントチャートシーケンス図の作成も可能です。{DiagrammeR}は現在アクティブに開発が進められている最中で、新しい機能がどんどん追加されていて、開発者はイケメンです。今後にさらに期待です。

ダイアグラム作成のオートメーション化、是非試してみてください。

まとめ

今回はレポートで使える可視化手法としてグラフ、テーブル、ダイアグラムを紹介しました。読者の方々はもちろんこれまでもグラフやテーブルを使っていたことでしょう。ですが、今回紹介した手法は従来のレポートの常識を覆す、一味違った可視化だったのではないでしょうか。しかもコピペ不要、オートメーション化されたレポートづくりです。今回の記事を参考に、あなたのレポートに彩りを添えましょう。

また、今回も入稿したオリジナルの原稿である、自動変換処理などを行う前のR Markdownファイルやサンプルなどをまとめて公開しておきます。

余談ですが、前回の記事を入稿した直後、1週間ほどイタリアに行っていました(仕事ですが……⁠⁠。イタリア国内の移動でライアンエアーに初めて乗ったんですが、着陸時に本当にファンファーレが鳴るんですね。びっくりしました。みなさんもヨーロッパ内を飛行機移動するときは試してみてください。

R Markdownとは全く関係のない余談でした。チャオ!!

次回は

これまで、HTMLレポートの作成を中心に紹介してきましたが、R Markdownでは同じ.RmdファイルからHTML形式以外のレポートを作成することも可能です。次回はPDFレポートやWord形式のレポートを作成する方法を紹介する予定です。

おすすめ記事

記事・ニュース一覧