今回の資料置き場 → http://kazutan.github.io/SappoRoR6/

R Markdownによるスライド生成

SappoRo.R #6

前田和寛(@kazutan)

2016/07/09

自己紹介

基本データ

icon

今回の内容

R Markdownでスライドを作ろう

  • R Markdownとは
  • Rmdでスライドを作るには
  • 各種フォーマットの紹介
  • {revealjs}
  • スライドの公開とpdf出力
  • はまりどころと回避策

R Markdown

R Markdownとは

  • MarkdownにRのコードを評価するブロック(Rチャンク)を組み込めるようにしたようなもの
    • 拡張子は.Rmd
    • Markdownの基礎があれば、Rチャンクを少し勉強すれば利用可能
    • RStudioを使うと抜群に楽になる
    • ただし文字コードの闇は深い
  • Kandai.R #1 にて発表したので、そちらを参照
    • (以下その時の内容を一部コピペ)

mdの基本

見出し(h1-h4)

# レベル1(h1)
## レベル2(h2)
### レベル3(h3)
#### レベル4(h4)
  • 文書構造を明確にするためにも、きっちり割り振る
    • レベル1は通常文書タイトル(章クラス)
    • レベル2は通常節クラス
    • 以下準じて下がっていく
  • 極力見出しの前後は空行をいれとくといいです

段落(p)と強制改行(br)

「もうすこしだ! この山を越えると、梅の林がある。――疾く参って梅林の木陰に憩い、思うさま梅の実みをとれ。――梅の実をたたき落して喰え」

 聞くと、奄々と渇にくるしんでいた兵も、  
「梅でもいい!」  
「梅ばやしまで頑張れ」と、にわかに勇気づいた。

 そして無意識のうちに、梅の酸っぱい味を想像し、口中に唾をわかせて、渇を忘れてしまっていた。

 ――梅酸渇を医す。
  • 上下に空行を挟むと、そこを段落ブロック(p)として認識
  • 行末に半角スペース2つ以上いれると強制改行(br)

番号なし箇条書き(ul>li)

- 箇条書き1
    - 箇条書き1-1
- 箇条書き2
    * 箇条書き2-1
    * 箇条書き2-2
  • 記号とスペースの後に内容を記述
    • どちらでもOK
    • 行頭の空白4つで1レベル下がる

番号あり箇条書き(ol>li)

1. 番号1
    1. 番号1-1
2. 番号2
    1. 番号2-1
    2. 番号2-2
  • 番号とピリオドとスペースの後に内容を記述
    • 行頭の空白4つで1レベル下がる

コードブロック(pre>code)

```
(ここにコード記述)
```
  • 入力した内容がそのまま表示されます
    • Rのコードは評価されません

強調表示

*斜体*、もひとつ_斜体_
**太字**、もひとつ__太字__
  • 上記のとおりです
  • 強調具合などはCSSなどに依存します

リンク、画像

- http://blog.kz-md.net/
- [リンク文字](http://blog.kz-me.net/)

![R looo](https://www.r-project.org/Rlogo.png)
![zou-san](pics/user.png)
  • 基本、相対パスや絶対パスの両方OK
  • URLでもOK

その他

  • 以下の内容もいけます
    • 脚注
    • Latex数式
    • 水平線
  • Pandoc Markdownなら大抵OKです

Rmdの基本

R Markdownの仕組み

  • R Markdownは以下の流れでドキュメントを生成します
    • まずはknitrパッケージでRチャンク部分などを処理
    • 生成されたmdファイルをpandocというドキュメント変換アプリで変換

対応する出力形式

  • いろんなものに対応しています(一部抜粋)
    • htmlファイル
      • 基本かつ最強。最もRmdを活かせるタイプ。
    • pdfファイル
      • tex環境が必要。いくつか地雷があるけど整えれば楽しい。
    • docxファイル
      • Officeをインストールしてなくても生成可能。
    • odtファイル
      • LibreOfficeなどで利用可能。
    • mdファイル
      • Githubやブログ記事向け。
    • rtfファイル
      • リッチテキスト形式。

Rチャンク

Rチャンクとは

  • Rのコードを記述したブロック
    • 基本的な書き方は以下の通り

      ```{r}
      head(iris)
      ```
    • ちなみに実行結果は以下の通り:

##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          4.9         3.0          1.4         0.2  setosa
## 3          4.7         3.2          1.3         0.2  setosa
## 4          4.6         3.1          1.5         0.2  setosa
## 5          5.0         3.6          1.4         0.2  setosa
## 6          5.4         3.9          1.7         0.4  setosa

Rチャンクの基本

  • 冒頭にYAMLヘッダ
    • ドキュメント設定などはここに記載
  • Rチャンクはいくつでも設置可
    • チャンクに名前をつけることも可能
    • 結構詳細にオプションを設定可能
    • Rオブジェクトを引き継ぐことも可能
  • 通常と(ほぼ)同じようにRが使える
    • パッケージ読み込み
    • データファイルへのアクセス
    • ただしパスについてはちょっと気をつける点も
  • 文字コード…
    • Why are you using SJIS?問題

Rチャンク オプション

  • そのRチャンクでの設定を記述
    • 設定項目はたくさんある
    • そのあたりはリファレンスを参照
    • 以下、絶対覚えるべきものだけ紹介
```{r chank-name, eval=TRUE}
head(iris)
```

echo(コード部の表示・非表示)

  • Rのチャンクコードを表示させるかどうか
    • echo=FALSEで非表示
    • あくまで表示に関することだけ
    • コード評価をするかどうかは影響しない
```{r, echo=FALSE}
head(iris)
```

eval(コード部の評価・非評価)

  • Rチャンクのコードを評価するかしないか
    • eval=FALSEで非評価
```{r, eval=FALSE}
head(iris)
```

include(レポートに組み込むか否か)

  • Rチャンクをレポートに組み込むかどうか
    • include=FALSEでレポートから除外
    • でもコードは評価されます
    • セットアップとか前処理とかパッケージ読み込みとかで重宝
```{r, include=FALSE}
library(zousan)
```

yamlヘッダ

yamlヘッダの基本

  • ドキュメントの全体的な設定など記述
  • yaml記法で記述
    • 左のスペース、重要
    • 多分感覚をつかむまでは、見様見真似でやっていったほうがいいです

主な項目

  • title:はドキュメントのタイトル
  • author:は名前
  • date:は日にち
  • output:は出力形式に関して
    • ここで出力を指定・設定
    • サンプルはこんな感じ

      ---
      title: "たいとるだよー"
      author: "かいたひとー"
      date: "199X年X月X日"
      output: html_document
      ---

レンダリング

Knitボタン

  • RStudioのKnitボタンでおk
    • うまくいったらViewerに表示
    • あるいは別ウィンドウにて表示

Rmdでスライドを作るには

Rでスライドを作るメリット

  • 分析からスライド生成までが完結
    • ぱわぽもきーのーともいらない
    • コピペ汚染からの開放
  • 再現性の確保
    • 同一の内容をそのまま再現できる
  • 再利用、配布が簡単
    • コードを簡単に再利用可能
    • テキストデータなので運用が簡単
  • 作るのが簡単
    • ドキュメント部分は基本Markdown
  • and more!!

基本的な考え方

  • 出力形式で、スライド用フォーマットを指定

    ---
    output: ioslides_presentation
    ---
  • オプション当てるなら、以下のような感じ:

    ---
    output:
      ioslides_presentation:
        toc: true
    ---
  • スライドは見出しで分割
    • ただし、フォーマットによって微妙に変わる
    • 大抵、level1もしくはlevel2まで
# スライド見出し
(以下内容)

## スライド見出し
(以下内容)

# スライド見出し 
(以下内容)

## スライド見出し
(以下内容)

対応フォーマット

  • rmarkdownデフォルトで使えるもの
    • ioslides
    • slidy
    • beamer
  • RStudioに組み込まれているもの
    • RPresentation(Rpres)
  • 他のパッケージを利用
    • revealjs など

ioslides

ioslidesの特徴

  • サンプルはこちら
  • わりといい感じのデザイン
    • ロゴも追加できたりする
    • ただし、テーマの切り替えなし
      • CSSによる設定自体は可能
  • 結構いい感じに使える

ioslidesの使い方

  • yamlは以下のように指定

    ---
    output: ioslides_presentation
    ---
  • オプションをつける場合は以下のような感じ

    ---
    output: 
      ioslide_presentation
        transition: slower
    ---
  • スライド区切りは#もしくは##の見出し
  • ---でタイトル無しスライドも可能

slidy

slidyの特徴

  • サンプルはこちら
  • シンプル(すぎる)デザイン
    • 機能も少なめ
    • 他のを使っていると、ちょっと物足りない
  • でも、縦にスクロールできる
    • なので一枚に載せれる情報が多くて便利
    • これがあるのは非常に貴重

slidyの使い方

  • yamlは以下のように指定

    ---
    output: slidy_presentation
    ---
  • オプションをつける場合は以下のような感じ

    ---
    output: 
      slidy_presentation
        toc: slower
    ---
  • スライド区切りは#もしくは##の見出し
  • ---でタイトル無しスライドも可能

R Presentation

Rpresの特徴

  • サンプルはこちら
  • RStudioで作成可能
    • reveal.jsがベースで、拡張子は.Rpres
    • RStudio内でPreview可能
    • Rでスライドづくりをはじめるなら、ちょうどいいかも
  • デザインの選択肢が狭い
    • 本来reveal.jsにはいろいろなテーマがある
    • しかし組み込まれていないので、CSSを持ってくる必要も
    • さらに独自仕様が組まれてて面倒(参考記事)

Rpresの使い方

  • RStudioメニューのFile - Nes File - R Presentationを選択
    • 必要事項を入力
  • 基本記法はMarkdown
  • スライド区切りは以下のようになる
 セクションタイトル(Level1見出し)
 ======

 スライドタイトル(Level2見出し)
 ------

 (ここに内容記述)

 スライドタイトル(Level2見出し)
 ------

 (ここに内容を記述)

beamer

beamerの特徴

  • texによるスライド作成パッケージがベース
    • サンプルはこちら
    • 本家ドキュメントはこちら
    • 出力フォーマットは.pdf
  • 記述はRmdでOK
    • Rmdからtexを作成し、それをpdfに出力してる(はず)
  • tex環境必須
    • 日本語を使うためには結構なことに
    • あくまでも「RStudioから直接使えるtex環境」

beamerの使い方

  • Texliveなどでtex環境を導入
    • Ubuntu環境だけしか検証してないので、近くのてふにしゃんにご相談を
    • texlive以外にも結構入れました…
  • 冒頭yamlは結局こんな感じに
---
output:
  beamer_presentation:
    latex_engine: lualatex
    toc: true
    slide_level: 2
    theme: Rochester
mainfont: IPAMincho
---

revealjs

revealjsの特徴

  • サンプルはこのスライド
  • reveal.jsというhtmlスライド用のjsライブラリをR(Rmd)に移植
    • 出力は.html
    • 元々結構人気なライブラリで、jsの方は日本語資料もけっこうある
  • テーマが豊富でデザインもいじりやすい
  • 機能、オプションが豊富
    • 横・縦と2Dプレゼンテーションが可能
    • たぶん今日触れた中で一番多機能

revealjsの使い方

  • パッケージをインストール&読み込み
devtools::install_packages("rstudio/revealjs")
library(revealjs)
  • 適当にR Markdownファイルを作成
  • 冒頭yamlを以下のよう修正

    ---
    output: revealjs::revealjs_presentation
    ---

以下、このスライドについて詳しく紹介。

revealjsのカスタマイズ

テーマ設定

  • 冒頭yamlを以下のように記述

    ---
    output:
      revealjs::revealjs_presentation
        theme: sky
    ---
  • もし存在しないテーマを設定したらエラーが出ます
    • その時に選べるテーマリストが出てくるのでそれで確認するという手も
  • フォントには注意
    • 元が海外なので日本語フォントはそのマシンのフォントに依存
    • この辺はそのOSのフォントとブラウザのフォントに依存するので省略

cssによる設定方法

  • 自分で設定したい内容をcssファイルに書き込んで読み込み可能
    • Rmdなら他のどのタイプでも利用可能
    • 必要ならば複数読み込むことも可能(らしい)
    • ただし、cssを使うのでcssの知識必須
    • 詳しくはrevealjsの本家ドキュメント参照
---
output:
  revealjs::revealjs_presentation:
    css: style.css
---

2カラムレイアウト

  • 本来は未実装
    • でも使いたいから実装した
    • cssで以下のコードを読みこませる:
.reveal .slides section .no-column {
  width: 96%;
}
.reveal .slides section .column1 {
  float: left;
  width: 48%;
}
.reveal .slides section .column2 {
  float: right;
  width: 48%;
}
  • 2カラムにしたいスライドには、以下のように<div>タグで挟み込む
<div class="column1">
(左側の内容)
</div>
<div class="column2">
(右側の内容)
</div>

ヘッダーの追加

  • 本家ドキュメントにも記載あり

    ---
    title: "Habits"
    output:
      revealjs::revealjs_presentation:
        includes:
          in_header: header.html
          before_body: doc_prefix.html
          after_body: doc_suffix.html
    ---

…正直言うと、これでは想定通り動かない

  • in_headerはhtmlの<head>ダグ内に差し込まれる
    • 主に<script>関連のをぶち込む場合に有用
    • でも多分あんまり出番なし
  • before_bodyはhtmlの<body>タグの一番頭に記述される
    • スライドヘッダーとして仕込める(このスライドの通り)
    • htmlファイルで、宣言とかは不要
  • after_bodyはhtmlの<body>タグの一番最後に記述される
    • revealjsスライドだと、そのままでは表示されない
    • それなりにスタイル設定しないと厳しい…

スライドの公開とpdf出力

公開方法

  • 出力はhtml
    • なので適当な場所でこれをUpすればOK
  • しかし内部ではjsやらcssやらが組み込まれている
    • デフォルトではbase64encodingされてて、該当htmlファイル内に突っ込まれてる
    • Plotなどの出力も同様
    • これが原因でjs可視化ライブラリが重たくなったり読み込まなくなったりする
  • 組み込みをOFFにできる
    • 冒頭yamlで以下のオプションを設定

      ---
      output:
        revealjs::revealjs_presentation:
          self_contatined: false
      ---
    • 別ディレクトリにcss、jsライブラリ、出力画像が吐き出される
    • ただしMathjaxライブラリ(数式表示用)だけは組み込まれる
      • これを別にしたい場合はyamlオプションで指定する必要あり
    • この場合、それらをまとめてオンラインにUpしないとダメ

pdf出力

  • すべてが静的になってしまうけど、共有しやすくはなる
  • reveal.jsは標準でpdfに出力する方法がある
    1. CHromeで表示
    2. URLのどっかに?print-pdfを埋め込む
    3. Cmd/Ctrl+ Pで印刷ダイアログを表示
    4. 「PDFで保存」でOK
  • これはおそらくreveal.js内のprint-pdf.jsプラグインの仕事
    • {revealjs}だと、デフォルト設定では動かない(崩れる)
  • 回避策はself_contained: falseを指定すること
    • 組み込むライブラリをhtmlに組み込まなければちゃんと出る
    • 手続きは前述の通りでOK
  • ただし、ちょっとした副作用が…
    • 他のjsライブラリを読み込んでいろいろやってる場合、たまに予期しない挙動をすることも
    • Pathでちょっと混乱することが…(自分がくらった)
    • このあたりはKnitrの詳しい仕様をチェックしないと…
  • ともあれ、単体でスライド作ってpdf出力するならこれでOKです

主な公開場所

  • RPubs
    • 一番楽で、@RPubsRecent に拾ってもらえるのでうれしい
    • self_contained: true(デフォルト)必須
    • でもログイン画面がhtmlなのはどうにかしてください
  • 自前のWebサイト
    • 一番いろいろできる
  • GitHub Pages
    • Git/GitHubを使っているなら、これもあり(Gitの知識必須)
  • RStudio connect
    • 詳しくは私に直接聞いてください
  • pdfでいろんなスライド公開サービスへ
    • 好きなところに投下してください

はまりどころと回避策

スライドが戻る(進まない)

  • 見出しがかぶるとこういう症状が発生します
    • htmlの{#id}が自動生成されるときに重複するため
    • これはPandocによる変換の時に付与されてます
      • この自動付与のルールについては、Pandoc Markdownの仕様書を見てください
  • 日本語&半角英数字のタイトルだと、半角英数字がかぶるだけで発生
    • {rmarkdown}がPandocに送るデフォルト設定の仕様です
    • 正直これ辛いです
  • 回避策
    • ひとまず、以下の呪文を唱えておいてください

      ---
      output:
        revealjs::revealjs_presentation:
      pandoc_args: [
        '--from', 'markdown+autolink_bare_uris+tex_math_single_backslash-implicit_figures'
      ]
      ---
    • これでも症状が出るときは見出しを修正するか、以下のように#idを手動で付与

       # ほげほげ {#hogehoge}

縦が足りない

  • まずは1枚に収まるように内容を再考しましょう
    • その内容は本当に必要ですか?
  • どうしても必要なら、以下の手段を
    • 適度なところで---を差し込んで複数に分ける
    • slidyを使う

動的なコンテンツがおかしくなる

  • htmlで出力してくるものが{revealjs}のcssと干渉してしまうため
  • 以下の呪文をsetupチャンクに仕込んでください
knit_print.htmlwidget <- function (widget, ..., options = NULL)
{
    file <- basename(tempfile(fileext = ".html"))
    selfcontained <- if(is.null(rmarkdown::metadata$self_contained)) TRUE else rmarkdown::metadata$self_contained
    htmlwidgets::saveWidget(widget, file = file, selfcontained = selfcontained)
    content <- if (selfcontained) {
        on.exit(unlink(file), add = TRUE)
        list(srcdoc = paste(readLines(file), collapse = "\n")) 
    }
    else {
        list(src = file)
    }
    x <- htmltools::tag("iframe", content)
    knitr::knit_print(x, options = options, ...)
}

参考資料

R Markdownのドキュメント

こちらもおすすめ

  • R Markdown CheatSheet
    • RStudio謹製のチートシート。
  • R Markdown Reference Guide
    • チャンクオプションやyaml設定などのリファレンス。
  • r-wakalang
    • rのチャットルーム。詳しくはこちら
    • 国内最強のメンバーが超優しく、そして即対応してくれます

Enjoy!