42 R Markdownで作るダッシュボード

この章では、flexdashboard パッケージの基本的な使い方を解説します。このパッケージは、R Markdown の出力形式をパネルやページを持つダッシュボードとして簡単に整形できます。ダッシュボードの表示内容は、文章、図・表、動的表示などで構成できます。

flexdashboard パッケージを利用するメリットは下記です。

  • ダッシュボード作成専用の R コード記述は最小限で済むため、わずかな練習ですぐにダッシュボードを作成できます。
  • 作成したダッシュボードは、自己完結型の HTML ファイルとして同僚に電子メールで送信できます。HTML ファイルを表示するための配信サーバは不要です。
  • flexdashboard パッケージは、shiny パッケージや ggplotly パッケージなどの “HTML ウィジェット” と組み合わせて、動的なダッシュボードにできます。

flexdashboard パッケージを利用するデメリットは下記です。

  • shiny パッケージでダッシュボードを作成するのに比べて、カスタマイズ性に劣ります。

この章で紹介している flexdashboard パッケージの使い方に関する包括的なチュートリアルは、参考資料セクションにあります。以降では、パッケージの主要な機能を説明した上で、linelist データを使ってアウトブレイクを調査するダッシュボードの構築例を紹介します。

42.1 準備

パッケージの読み込み

このハンドブックでは、パッケージを読み込むために、pacman パッケージの p_load() を主に使用しています。p_load() は、必要に応じてパッケージをインストールし、現在の R セッションで使用するためにパッケージを読み込む関数です。また、すでにインストールされたパッケージは、R の基本パッケージである base (以下、base R)の library() を使用して読み込むこともできます。R のパッケージに関する詳細は R の基礎 の章をご覧ください。

pacman::p_load(
  rio,             # データのインポート・エクスポート
  here,            # ファイルパスの指定
  tidyverse,       # データの加工と可視化
  flexdashboard,   # R Markdown レポートのダッシュボード版
  shiny,           # 動的なダッシュボード、作図
  plotly           # 動的な作図
)

データのインポート

エボラ出血熱の流行をシミュレートしたデータセットをインポートします。お手元の環境でこの章の内容を実行したい方は、 クリックして「前処理された」ラインリスト(linelist)データをダウンロードしてください>(.rds 形式で取得できます)。データは rio パッケージの import() を利用してインポートしましょう(rio パッケージは、.xlsx、.csv、.rds など様々な種類のファイルを取り扱うことができます。詳細は、インポートとエクスポート の章をご覧ください)。

# linelist をインポートする
linelist <- import("linelist_cleaned.rds")

linelist の最初の 50 行を以下に表示します。

42.2 新規 R Markdown ファイルを作成する

パッケージをインストールをした後、File > New file > R Markdown と選択して新規 R Markdown ファイルを作成してください。

開いたウィンドウから “From Template” を選択して、次に、“Flex Dashboard” テンプレートを選んでください。その後、ドキュメントの名前をつけるように促されます。今回の例では、R Markdown ファイルを “outbreak_dashboard.Rmd” と命名しましょう。

42.3 スクリプト

ファイルに記述するスクリプトは、R Markdown 記法そのものです。そのため、R Markdown で作るレポート の章で解説した内容や記法と同じです。このセクションで、再度、簡単に記法を紹介し、この章で扱う R Markdown の出力形式との違いを示します。

YAML ヘッダ

記述するスクリプトの一番上には、“YAML” ヘッダがあります。YAML ヘッダは、3 本のダッシュ(---)で始め、3 本のダッシュ(---)で閉じる必要があります。YAML ヘッダのパラメータは key:values の組み合わせで記述します。YAML 記法では、半角スペースによるインデントとコロンの記述が大切ですkey:value パラメータはイコール記号ではなく、コロンで分けらていることに注意が必要です。

YAML ヘッダには文書のメタデータを記述する必要があります。YAML ヘッダに記述される(インデントされていない)パラメータの順番は重要ではありません。例えば次のような形です。

title: "My document"
author: "Me"
date: "`r Sys.Date()`"

インラインコードを書く(r に続いてバックティックの中に記述する)ように、YAML ヘッダの中で R コードを記述できます。また、上記 YAML ヘッダ例内の date パラメータにあるように、二重引用符中にも記述できます。

必須の YAML ヘッダパラメータは output: です。このパラメータは、どのような種類のファイルを生成するかを指定します(例: html_documentpdf_documentword_documentpowerpoint_presentation など)。flexdashboard パッケージにおいて、このパラメータの指定は少し混乱するかもしれません。output: パラメータを必ず output:flexdashboard::flex_dashboard と指定する必要があります。コロンの個数とアンダースコアに注意してください。ダッシュボード固有の追加のパラメータは YAML ヘッダ内の ouput:flexdashboard::flex_dashboard パラメータの行末に追加のコロンを入力し、その次の行から半角スペースで行頭をインデントして続くことが多いです。(具体例は、以下のコードにある orientation:vertical_layout: のパラメータを参照してください)。

title: "My dashboard"
author: "Me"
date: "`r Sys.Date()`"
output:
  flexdashboard::flex_dashboard:
    orientation: rows
    vertical_layout: scroll

上記に示したように、2 つの半角スペースで作られたインデントがサブパラメータの記述に利用されています。サブパラメータを追加する場合は、key:values: のように、上位となるパラメータの行末にコロンを追加で入力するのを忘れないようにしましょう。

ロジカル型値をパラメータに与える必要がある場合は、YAML ヘッダ内では小文字で記述される必要があります(truefalsenull)。タイトルなど key:values 内の values の一部に、もしコロンやカッコなど記号を含む場合は values 全体を二重引用符で囲んでください。詳しくは以降のセクションで都度例示される YAML ヘッダを参照してください。

コードチャンク

R Markdown は複数の「チャンク(コードチャンク)」を含むことができます。複数行の R コードをチャンク内に書けて、これらのコードは通常の R スクリプトとして動作します。

コードチャンクは、3 つのバックティックと、小文字の “r” が入った波括弧で作成され、3 つのバックティックで閉じられます。 キーボードショートカット、“Ctrl + Alt + i”(Mac では Cmd + Shift + r)、と入力するか、RStudio スクリプトエディタの上端にある “insert a new code chunk” と表示されている緑のボタンをクリックすることで新しいチャンクを作成してみてください。コードチャンクの例を以降、多数例示しています。

本文(ナラティブテキスト)

R コード「チャンク」の外には、本文(ナラティブテキスト)を書くことができます。R Markdown で作るレポートで解説されているように、アスタリスク(*)1 つでテキストを囲むことで斜体にできます。あるいは、アスタリスク 2 つ(**)でテキストを囲むことで強調体にできます。箇条書きや番号付き箇条書きは、改行、行頭インデント、行末にスペースが 2 つ入力された場合などで表示が変わります。

R Markdown で作るレポート の章に記述されたように、インライン R コードはバックティック()で囲まれたコード(``1+1` ``)の先頭に “r” をつけることで入力できます(前述した YAML ヘッダ例の date パラメータを参照してください)。

見出し

R Markdown で作るレポート の章で説明したように、見出しの大小はハッシュ記号の入力個数で表現されます。

flexdashboard パッケージでは、見出し 1(#)はダッシュボードの「ページ」を作成します。見出し 2(##)は orientation: パラメータに応じてカラム(水平方向の表示枠)やロウ(垂直方向の表示枠)を作ります(詳細は下記を参照ください)。見出し 3(###)は図、表、テキストなど表示のためのパネルを作成します。

# 見出し1 (ページ)

## 見出し2 (垂直方向か水平方向に下位見出し内容を配置する)

### 見出し3 (図、表などを表示するパネル)

42.4 セクションの属性

ダッシュボードの一部に適用する属性を指定するには、通常の R markdown 記法と同様に、見出しの後、波括弧 { } の中に key=value オプションを入れます。例えば、典型的な HTML の R markdown レポートでは、## My heading {.tabset} とすることで、小見出しをタブにまとめることができます。

前段落の例では、見出しのテキスト部分の後に属性が記述されていることに注意してください。これらは、R コードチャンクの上部に入力される knitr パッケージのオプション(例えば、 out.height =)とは違います。

flexdashboard パッケージの特徴的な属性には以下があります。

  • {data-orientation=}rows(ロウ:垂直方向配置)または columns(カラム:水平方向配置)のいずれかを値に設定します。ダッシュボードに複数のページがある場合は、各ページにこの属性を追加して、内容を配置する方向を指定してください (詳細は レイアウトセクション で説明しています)。
  • {data-width=}{data-height=}:同じ表示方向(水平方向配置または垂直方向配置)にレイアウトされたグラフ、カラム、ロウの相対的サイズを設定します。絶対的サイズは、flexbox CSS 表示エンジンによって、どのようなディスプレイデバイスでも表示範囲が最適になるように調整されます。
    • グラフの高さは、YAML ヘッダパラメータの vertical_layout: fillvertical_layout: scroll のどちらを設定するかにも依存します。scroll に設定した場合、グラフの高さは R コードチャンクの一般的な fig.height = オプションを反映します。
    • サイズ指定に関する完全なドキュメントは flexdashboard パッケージの公式ウェブサイト を参照してください。
  • {.hidden}:ページの最上段に表示されるナビゲーションバーから特定のページを除外するために利用します。
  • {data-navmenu=}:ページレベルの見出し(#)に適用します。該当のページをナビゲーションバーのドロップダウン内のメニューとして表示します。 ドロップダウンメニューの名前を二重引用符で囲んで入力してください。 「レイアウト」セクション内の例をご参考ください。

42.5 レイアウト

このセクションではダッシュボードのレイアウトを以下の方法で整形します。

  • R Markdown の見出し記法(#、##、##など)を使用し、ページ、カラム・ロウ、チャートを追加する
  • YAML ヘッダパラメータの orientation:rows またはcolumns のいずれかに指定する
  • ブラウザの領域いっぱいにレイアウトを表示するか、スクロールさせて表示するかを指定する
  • 特定のセクションの見出しにタブを追加する

ページ

R Markdown で、見出しレベル 1(#)はダッシュボードの「ページ」を意味します。デフォルトの設定では、ページは、一番上に表示されるナビゲーションバーに順番に並んで表示されます。

ページの見出しに {data-navmenu=} 属性を付けることで、ナビゲーションバー内の「メニュー」としてページをまとめることができます。等号演算子(=)の前後にスペースを入れると、うまくいきませんので、気を付けてください!

上記スクリプトの実行結果です。

また、{.sidebar} 属性を追加することで、ページやカラムをダッシュボードの左側にある「サイドバー」として表示できます。サイドバーには(どのページからも表示可能な)テキストを表示したり、shiny パッケージの動的機能を組み込んでいる場合は、スライダーやドロップダウンメニューなどのユーザ入力用コントローラを表示するのに便利です。

上記スクリプトの実行結果です。

内容の配置方向指定

YAML ヘッダパラメータに orientation: を設定して、R Markdown の見出し 2(##)要素以下の内容を水平方向配置または垂直方向配置で並べるか指定します。orientation: columns(水平方向配置)または orientation: rows (垂直方向配置)のどちらかを設定しましょう。

見出し 2(##) は、YAML ヘッダパラメータの orientation 設定に基づいて、新規カラム(水平方向配置)または新規ロウ(垂直方向配置)として解釈されます。

例えば orientation: columns と設定すると、見出し 2 がダッシュボードのページに新規カラム(水平方向配置)として追加されます。以下の例のダッシュボードには、1 つのページ内に 2 つのカラムがあり、合計で 3 つのパネルがあります。カラムの相対的な幅は、以下のように {data-width=} 属性で調整できます。

上記スクリプトの実行結果です。

orientation: rows を設定すると、見出し 2 はカラムの代わりに新規ロウを作成します。以下は上記と同じスクリプトですが、orientation: rows が設定されており、見出し 2 がカラムではなく ロウを生成するようになります。以下のように、{data-height=} で行の相対的な高さを調整することもできます。

上記スクリプトの実行結果です。

ダッシュボードに複数のページがある場合、各ページのヘッダーに {data-orientation=} 属性を追加することで、各特定ページごとに配置方向を指定できます(引用符なしで rows または columns のどちらかを指定できます)。

タブ

他の HTML R Markdown の出力と同様に、{.tabset} 属性で表示内容をタブに分割できます。

この属性を必要な見出しの後に追加するだけです。その見出しの下位にある小見出しは、タブとして表示されるようになります。例えば、下記のスクリプトでは、右の “Colums 2”(##)がタブ化されており、流行曲線(エピカーブ)パネルと表パネル(見出し 3 ###)の内容がタブで表示されるようになりました。

配置方向の設定が row であれば、垂直配置方向でも同じ分割ができます。

上記スクリプトの実行結果です。

42.6 表示内容を追加する

それでは、ダッシュボードを作り始めましょう。この章で作成するシンプルなダッシュボードは、1 ページ、2 カラム、4 パネルで構成されます。パネルをひとつひとつ組み立てながら解説します。

表示内容には、テキスト、ggplot によるプロット、テーブルなど、R の標準的な出力を簡単に含めることができます(詳しくは、見やすい表の作り方の章を参照してください)。他の R Markdown スクリプトのように、R コードチャンク内に出力を生成するコードを追加するだけです。

注:この章で作成する R markdown スクリプトの完成形と HTML ダッシュボードの出力をダウンロードできます。詳しくは、ハンドブックとデータのダウンロードの章をご覧ください。

テキスト

Markdown テキストを入力し、他の R Markdown 出力のようにインラインコードを含めることができます。詳細についてはR Markdown で作るレポートの章を参照してください。

この章で作成するダッシュボードには、集計した結果を表示するテキストパネルが用意されています。パネル内にはアウトブレイクで報告された最新の入院日と症例数が自動的に変わるテキストを含みます。

パネルには表などを出力する R コードチャンクを含められます。この場合、テーブルを表示するために knitr パッケージの kable() 関数を使用すると、出力が最も見栄えよく見え、かつ、ウィンドウサイズに合わせて表示されます。flextable パッケージの関数を利用すると、要約表や、一部分を切り落とした表を作成できます。

以下の例では linelist オブジェクトに count() コマンドを適用して、病院ごとの症例数の要約表を作成しています。最終的に、この要約表は knitr::kable() に渡され、ページ上では右側にスクロールバーが表示されます。kable()kableExtra パッケージを使った表のカスタマイズについては、こちらのドキュメント を参照してください。

上記スクリプトの実行結果です。

もし、「ページ」内で、ユーザがデータフレームを抽出、並び変え、操作できるような動的な表を表示したい場合は、以下のコードのように、DT パッケージと datatable() 関数を使用します。

以下のサンプルコードで、linelist データフレームが表示されます。rownames = FALSE を設定すると行番号表示を省略し、水平方向のスペースを節約できます。filter = "top" を設定すると、すべての列の一番上にフィルタを配置できます。その他の指定項目はリスト型にまとめて options = に渡します。以下では、options に 5 行ごとにデータフレーム内容が表示されるように pageLength = を設定し、かつ、ユーザが下部のスクロールバーを使って水平方向にスクロールできるように scrollX = を設定しています。引数 class = 'white-space: nowrap' は、各行が 1 行表示となることを保証します(各セル内で改行されません)。その他の引数や値については、 こちらを参照するか、?datatable と入力してみてください。

DT::datatable(linelist, 
              rownames = FALSE, 
              options = list(pageLength = 5, scrollX = TRUE), 
              class = 'white-space: nowrap' )

プロット

通常の R スクリプトでプロットするようにダッシュボードページにプロットを表示できます。以下の例では、incidence2 パッケージを使用して、2 つの簡単なコマンドで年齢層別の「流行曲線(エピカーブ)」を作成しています(流行曲線(エピカーブ) の章を参照してください)。他にも、ggplot() を使用して、同じようにプロットを表示できます。

上記スクリプトの実行結果です。

動的なプロット

また、標準的な ggplot や他のプロットオブジェクトを plotly パッケージの ggplotly() に渡すこともできます (動的な図の作成 の章を参照してください)。この関数はプロットを動的にします。つまり、ユーザがプロットを「ズームイン」したり、すべての観測値(この例では、流行曲線(エピカーブ)中の年齢層別、週あたりの症例数)をマウスカーソルをグラフ上に置くことで表示したりできます。

age_outbreak <- incidence(linelist, date_onset, "week", groups = age_cat)
plot(age_outbreak, fill = age_cat, col_pal = muted, title = "") %>% 
  plotly::ggplotly()

上記スクリプトをダッシュボードで表示するとこんな感じです(gif)。この動的表示機能は、ダッシュボードを静的ファイルとして電子メールで送信しても機能します(インターネットに接続されていなくても表示可能)。

HTML ウイジェット

HTML widgets for R ウェブページには、多数の HTML ウィジェットのサンプルがあります。HTML ウィジェットはi JavaScript のライブラリを利用して動的操作性を高める R パッケージの特殊なダッシュボードパーツです。HTML ウィジェットは R Markdown 出力(flexdashboard など)や Shiny ダッシュボードに埋め込むことができます。

HTML ウィジェットに利用できる R パッケージの一般的な使用例は、以下があります。

  • Plotly パッケージ(この章と、本ハンドブックの動的な図の作成の章で使用されています)。
  • visNetwork パッケージ(本ハンドブックの感染連鎖の図式化の章で使用されています)。
  • Leaflet パッケージ(本ハンドブックのGIS の基礎の章で使用されています。
  • dygraphs パッケージ(時系列データを動的に表示するのに便利です)
  • DT (datatable()) パッケージ((フィルタ、ソートなどの機能を持つ動的なテーブルを表示するのに便利です)。

以下は、visNetwork パッケージを使用した感染連鎖をダッシュボードページに追加する例です。R Markdown スクリプトの「Column 2」見出し 2 に追加する新しいコードのみを表示しています。追加するコード例の詳細は、ハンドブックの感染連鎖の図式化の章をご参照ください。

上記スクリプトの実行結果です。

42.7 コードの構造化

ここまでの例のようにすべてのコードを flexdashboard パッケージを利用した R Markdown スクリプト内に記述できます。また、より整理された簡潔なダッシュボード用の R スクリプトを作成するために、他の R スクリプトで管理または作成されたコード・図を呼び出せます。他の R スクリプトの呼び出しについては、R Markdown で作るレポートの章でより詳細に説明しています。

42.8 Shiny パッケージを利用する

R パッケージの shiny パッケージを共に用いると、ユーザの入力をより反映させるダッシュボードを作成できます。例えば、ユーザに管轄地域や日付範囲を選択(例、表示されるデータにフィルターをかけるなど)させ、選択内容に対応してグラフ表示が変化するようにできます。flexdashboard パッケージを用いた R スクリプトに shiny パッケージの柔軟性を組み込むには、スクリプトに少し変更を加えるだけです。

flexdashboard パッケージを使わなくても、shiny パッケージを使ってアプリ・ダッシュボードを作成できます。ハンドブックのShiny で作るダッシュボードの章では、この方法について、shiny パッケージ固有の少々の構文、アプリのファイル構造、共有・配信方法の選択肢(無料の配信サーバを含む)についての概要を説明しています。構文と一般的なヒントは、flexdashboard パッケージの利用にも当てはまります。

しかしながら、flexdashboard パッケージと shiny パッケージの機能を共に用いると、作成されるダッシュボードを根本的に変えることになります。shiny パッケージを組み込むと電子メールで送信し、誰でも開いて見ることができるような HTML 出力は生成されません。代わりに「アプリ」になります。スクリプトの上部にある「Knit」ボタンは「Run document」アイコンに置き換えられます。「Run document」アイコンを押すと、あなたのローカルコンピュータに、動的なダッシュボード(アプリ)のための配信サーバ(インスタンス)が動作しはじめます。

shiny パッケージの機能を用いたダッシュボードを共有するには、以下のいずれかが必要となります

  • R markdown スクリプトをユーザに送り、ユーザが自分の PC で R スクリプトを開き、アプリを実行する、または
  • アプリ・ダッシュボードを、ユーザがアクセス可能な配信サーバにホストする

上記のように、shiny パッケージの機能を統合することにはメリットもありますが、複雑さもあります。もし、電子メールで簡単に共有することが優先事項であり、shiny パッケージの動的機能を必要としないのであれば、「動的なプロット」セクションで例示したような ggplotly() による限定された動的機能の採用を考慮してください。

以下では、ここまでの例で使用した “outbreak_dashboard.Rmd” を使い shiny パッケージを導入する簡単な例を紹介します。shiny を flexdashboard パッケージと共に用いるための詳細なドキュメントは、オンラインで入手可能です。

shiny パッケージを利用する設定

以下のように、YAML ヘッダに runtime: shiny パラメータを output: パラメータと同じインデントレベルで追加することで、flexdashboard パッケージと shiny パッケージの機能を共に用いることができます。

---
title: "Outbreak dashboard (Shiny demo)"
output: 
  flexdashboard::flex_dashboard:
    orientation: columns
    vertical_layout: fill
runtime: shiny
---

ユーザからの入力値を集約する入力用ウィジェットの配置に「サイドバー」を有効にすると便利です。「レイアウト」セクションで説明したように、カラム用の見出し 2 を作成し、{.sidebar} オプションを定義すると、左側にサイドバーが作成されます。このサイドバー用カラム内に shiny パッケージの input コマンドを含む、本文テキストと R コードチャンクを追加できます。

アプリやダッシュボードが配信サーバでホストされていて、複数のユーザが同時に使用する可能性がある場合に有用な方法があります。まず、スクリプト内で最初に作成する R コードチャンクに global という名前を付けます。このコードチャンクにデータをインポート・ロードするためのコマンドを記述します。この特別な名前のコードチャンクは特別に振る舞い、チャンク中でインポートされたデータは一度だけインポートされ(繰り返されることなく)、アプリやダッシュボードにアクセスするすべてのユーザが利用できます。この設定により、アプリの起動速度が向上します。

shiny パッケージを利用した実際の例

このセクションでは、flexdashboard パッケージを利用した R markdown スクリプト “outbreak_dashboard.Rmd” に shiny パッケージを追加します。追加する機能は、ユーザがドロップダウンメニューから病院を選択し、選択された病院の症例のみを反映した流行曲線(エピカーブ)を、動的なプロットとタイトルとともに表示する機能です。以下に作成概要を箇条書きにします。

  • YAML ヘッダに runtime: shiny パラメータを追加する。
  • スクリプトで最初に作成する R コードチャンク(セットアップチャンク)の名前を global に変更する。
  • サイドバーを次の内容で作成する:
    • 個々の病院名を含むベクトルを作成するコード
    • 病院名を選択する selectInput() コマンド (shiny パッケージに含まれるドロップダウンメニュー)。選択内容は hospital_choice オブジェクトとして保存され、他のコードから input$hospital_choice として参照できます。
  • 流行曲線(エピカーブ)を表示するコード(Column 2、見出し 2 の下位見出し内)は renderPlot({ }) 中に記述されており、以下を含みます。
    • linelist オブジェクト内の hospital 変数(列)を input$hospital_choice に保存されている値に制限するフィルタ
    • input$hospital_choice` に保存されている値を反映した動的なプロットとタイトル

input$ に保存されている値を参照するコードは、(値に対応して表示(rendering)を変えるために) render({}) 関数の中になければならないことに注意してください。

以下は、YAML ヘッダ、セットアップチャンク、サイドバーなどの記述を含む R markdown スクリプトの最初の部分です:

以下は「Colums 2」と下位見出し、動的な流行曲線(エピカーブ)プロットのための記述です。

上記を統合したダッシュボードの表示です。

shiny パッケージを利用したその他の例

shiny パッケージの動的機能と leaflet パッケージ内の地図を表示するためのウィジェット機能を使い、ダッシュボードに shiny パッケージと flexdashboard パッケージを利用した、健康関連を扱った例についてはオンラインブックGeospatial Health Data: Modeling and Visualization with R-INLA and Shiny の該当章をご覧ください。

42.9 ユーザとの共有、配信方法

shiny パッケージの機能を含まないダッシュボードは、HTML ファイル(.html)を出力し、(サイズが許せば)メールで送信できます。この方法は、「ダッシュボード」をレポートとして送ることができ、ウェブサイトとしてホストするための配信サーバを用意する必要がないため、便利です。

shiny パッケージの機能を利用した場合、出力ファイルをメールで送ることはできませんが、スクリプト自体を R ユーザに送ったり、「Shiny パッケージを利用する」セクションで説明したようにダッシュボードを配信サーバでホストすることが可能です。

42.10 参考資料

この章で参考にした優れたチュートリアルは、以下のとおりです。これらを参考にすれば、おそらく 1 時間以内にあなた自身でダッシュボードを作成できます。

https://bookdown.org/yihui/rmarkdown/dashboards.html

https://rmarkdown.rstudio.com/flexdashboard/

https://rmarkdown.rstudio.com/flexdashboard/using.html

https://rmarkdown.rstudio.com/flexdashboard/examples.html