はじめに
※この記事はRendering PowerPoint Presentations with RStudio – RStudio Supportを元ネタとして要約したり補足したりしたものです。
最近のPandocのアップデートによって、markdownからPowerPointプレゼンテーションの生成が可能になりました。
~~RStudioからこの機能をつかうためには、バージョン2.xのPandocがバンドルされているプレビュー版のRStudio(RStudio Preview - RStudio)が必要です。~~RStudio 1.2がリリースされたので、プレビュー版は必要なくなりました。Download RStudio - RStudioからダウンロードできます。
また、rmarkdown
パッケージを最新版にしておきましょう。
install.packages("rmarkdown")
.Rmdの作成とレンダリング
R MarkdownからPowerPointプレゼンテーションを出力するためには、YAMLフロントマターでoutputにpowerpoint_presentation
を指定します。
---
title: "Untitled"
output: powerpoint_presentation
---
あるいは、File > New File > R Markdown > Presentationと選択すると、中にPowerPointという選択肢がありますので、これを選べばテンプレートから作成することもできます。
まずはテンプレートをそのままKnitしてPowerPointファイルを生成してみましょう。RStudioを使っている場合は、KnitボタンまたはCommand+Shift+k
(Windows/LinuxならCtrl+Shift+k
)でPowerPointファイルを生成できます。または、次のコマンドを実行してKnitすることもできます。
rmarkdown::render("in.Rmd", output_format = "powerpoint_presentation")
次のような.pptxファイルが生成されましたか?
Markdown記法の利用
PandocのMarkdown(Pandoc - Pandoc User’s Guide)でサポートされている要素のほとんどはPowerPointに出力することができます。例を見てみましょう。
### Markdownの基本的な記法
- 箇条書き
- *イタリック*
- **太字**
- ~~取り消し線~~
- ~下付き~ `inline code` ^上付き^
- $y = ax + b$
上記の記述を含むファイルをKnitすると次のようなスライドが生成されます。
このような一般的な要素のほとんどはPowerPointの対応する要素に変換されています。そのため、出力された.pptxファイルを開いてテーマを適用したり、スタイルを編集したりした場合に変更が適切に反映されます。
さらに、スライド作成に有用な次のような記法もサポートしています。
画像とテーブル
画像はスライドサイズに合うように自動的に調整されます。キャプションを入れた場合は画像の下に表示されます。また、必要であれば画像とキャプションのそれぞれにリンクを設定することもできます。
### images
![caption](path/to/image.jpg)
テーブルを挿入した場合、テンプレートのスタイルが自動的に適用されます。また、キャプションも追加できます。
### table
| hoge | fuga | piyo |
|:---- |:----:| ----:|
| foo | bar | baz |
Table: this is caption
画像とテーブルは必ず新しいスライドに配置される、という点に注意して下さい。画像やテーブルと共存可能な要素は、ヘッダーとキャプションだけです。
ただし、次に説明する2カラムレイアウトを利用すればテキストと画像やテーブルを共存させられます。
2カラムレイアウト
画像の横に説明を入れるようなレイアウトはPowerPointではありがちです。これは、div記法を使うことで実現できます。
具体的には、2つのdivを含むdiv要素を作成し、外側のdivにはcolumns
クラスを、内側のdivにはcolmn
クラスを設定します。
::::::::::::::: {.columns}
::: {.column}
- 何らかの説明
- 何らかの説明2
- 何らかの説明3
:::
::: {.column}
![hoge](fig/icon.jpg)
:::
::::::::::::::::::::::::::
ノート
ノートも作成できます。
ノートの内部でもいくつかの記法は使えますが、もともとノート内はそれほど柔軟に書式設定できるわけではない、という点に注意して下さい。設定できるのは、ボールド、斜体、箇条書きといったごく限られた書式のみです。
::: notes
This is a speaker note.
- Use basic Markdown
- like this list
- *and inline formatting*
:::
テンプレート
デフォルトでは、4:3の画面サイズで標準の質素なテンプレートが適用された.pptxファイルが出力されます。これが気に入らない場合は、YAMLフロントマターでテンプレートを指定することができます。テンプレートに指定するファイルは、次の4つのレイアウトを最初の4つのレイアウトとして含む必要があります。
- タイトルスライド(Title Slide)
- セクション見出し(Section Header)
- タイトルとコンテンツ(Title and Content)
- 2つのコンテンツ(Two Content)
最近のバージョンのPowerPointに含まれているテンプレート、あるいはそれを編集したテンプレートであれば、おそらく問題なく使えるでしょう。
---
title: "Untitled"
author: '@nozma'
date: "3/6/2019"
output:
powerpoint_presentation:
reference_doc: templete.pptx
---
構造化
PowerPointプレゼンテーションにはタイトル、セクション、コンテツスライドといった階層構造があります。Markdownにも#
, ##
, ###
といったヘッダの階層構造があります。
デフォルトでは、コンテンツスライドのヘッダに対応付けられるヘッダのレベルは、テキスト内での使われ方に応じて自動的に設定されます。すなわち、ヘッダに続く要素が次のレベルの他のヘッダではなく、コンテンツ本体(例えば箇条書き)であるようなヘッダのレベルがスライドのヘッダに対応付けられます。例えばテキスト内で#
しか使っていなければ、#
がスライドのヘッダに対応付けられる、というわけです。
スライドヘッダに対応するヘッダレベルは、YAMLフロントマターで任意に設定することもできます。
---
title: "slide title"
output:
powerpoint_presentation:
slide_level: 3 # ← この場合は ### がスライドヘッダになります
---
スライドヘッダに対応するヘッダのレベルに対して、他のレベルのヘッダは次のように振る舞います。
- スライドヘッダレベルと等しい...常に新しいスライドが始まる
- スライドヘッダレベルより上位...セクション見出しが挿入される
- スライドヘッダレベルより下位...スライド内部の見出しとして使われる
また、水平線---
は常に新しいスライドを開始します。
Rコードチャンク
当然ですが、Rのコードの実行結果をスライドに含めることもできます。
テーブル
データフレームはそのままでは整形されず、ターミナルへの出力と同じ形式で表示されます。
PowerPointのテーブル形式で出力したければ、knitr::kable()
を使いましょう。
knitr::kable(head(mtcars, 3))
プロット
プロットは自動的にスライドサイズに合う画像として挿入されます。画像サイズを変更したければfig.width
やfig.height
というチャンクオプションを調整してみると良いでしょう。
Webサイト
HTML WidgetやShinyはwebshot
パッケージ(CRAN - Package webshot)とPhantomJS(PhantomJS - Scriptable Headless Browser)を使うことでスクリーンショットをスライドに取り込むことができます。
まずはwebshot
とPhantomJSをインストールしましょう。
install.packages("webshot")
webshot::install_phantomjs()
両者がインストールされていれば、あとは普通にコードチャンクを書くだけです。試しにleaflet
パッケージで地図を入れてみましょう。
library(leaflet)
leaflet() %>%
addTiles() %>%
setView(-122.36075812146, 47.6759920119894, zoom = 13)
Webサイトの読み込みに時間がかかって上手くスクリーンショットが撮影できない場合は、チャンクオプションでディレイを設定すると良いかもしれません。
{r screenshot.opts=list(delay=1)}