Rで解析:R MarkdownからWordとPowerPointの文書を作る「officedown」パッケージ
「officedown」パッケージは、R Markdownで書いた内容から、表や図に番号の付いたWordの報告書やPowerPointのスライドを作れるパッケージです。渡すのはRのコードと文章を書いたRmdファイルで、データフレームはそのまま表になり、グラフも文書に入ります。用紙の向きや余白、表と図の番号の付け方をRの側で決められるので、Wordで開いてから体裁を整え直さずに済みます。R Markdownの変換にPandocを使うため、RStudioなどでPandocが使える環境が前提です。定例の集計結果を毎回同じ体裁のWordやPowerPointで配っている人は、作業をRの中で完結できるのではないかと考えます。
パッケージバージョンは0.4.3。Windows 11 x64 (build 26200)のR version 4.6.1で確認しています。
パッケージのインストール
下記コマンドを実行してください。
# パッケージのインストール
install.packages("officedown")
# パッケージの読み込み
library("officedown")
# Rmdファイルの変換に使うパッケージを読み込み
library("rmarkdown")
# 用紙や文字の書式の指定に使うパッケージを読み込み
library("officer")コマンド例
詳細はコメント、パッケージのヘルプを確認してください。
R Markdown:Rのコードと文章を1つのファイル(Rmdファイル)に書き、コードの実行結果を入れた文書に変換する仕組み。変換にはPandocというソフトを使います。RStudioには同梱されています。
ブロックとラン:officerパッケージの言い方で、ブロックは段落や目次などの文書のまとまり、ランは段落の中の書式をそろえた文字のまとまりです。
以降の例では、Rmdファイルの中身を writeLines で書き出し、render の output_format に各コマンドを渡します。Rmdファイルの中のコードは、ここで作ったデータを読みます。ファイルは作業フォルダに書き出されます。
# 京野菜の出荷量データを作成
kyoto_veg <- data.frame(
品目 = c("九条ねぎ", "賀茂なす", "万願寺とうがらし", "聖護院かぶ", "京たけのこ"),
産地 = c("伏見区", "北区", "舞鶴市", "左京区", "長岡京市"),
出荷量 = c(820, 310, 540, 270, 460)
)
# 宇治茶の茶園ごとの試飲評価データを作成
uji_tea <- data.frame(
茶園 = c("宇治田原", "和束町", "南山城村", "宇治市"),
香り = c(4.2, 4.5, 3.9, 4.1),
渋み = c(3.1, 2.8, 3.4, 3.0)
)Wordの文書を作成:rdocx_documentコマンド
表と図に「表 1:」「図 1:」の形で番号を付け、本文から番号で参照するA4横向きの報告書を作ります。番号はWordのフィールドとして入るので、Wordで開いて「フィールドの更新」をすると振られます。
| オプション | 意味 | 初期値 |
|---|---|---|
| base_format | 元にする出力形式。bookdown::word_document2 も指定できる。その場合 number_sections は FALSE になる | “rmarkdown::word_document” |
| tables | 表の書式(スタイル、キャプションの位置・番号の付け方など)をリストで指定 | list() |
| plots | 図の書式(配置、キャプションの番号の付け方など)をリストで指定 | list() |
| lists | 箇条書きに使うWordのスタイルをリストで指定 | list() |
| mapstyles | 置き換えるスタイルの名前付きリスト。list(“Normal” = c(“Author”, “Date”)) で Author と Date の段落を Normal にする | list() |
| page_size | 用紙の大きさと向き。officer::page_size で指定 | NULL |
| page_margins | 用紙の余白。officer::page_mar で指定 | NULL |
| reference_num | TRUE で見出しへの参照を節番号(3.2 など)で、FALSE で見出しの文字で出す | TRUE |
| … | word_document に渡すオプション | なし |
# 報告書の中身を書き出す
rmd_word <- c(
"---",
"title: \"京野菜の出荷報告\"",
"---",
"",
"## 品目ごとの出荷量",
"",
"出荷量は表\\@ref(tab:veg)と図\\@ref(fig:veg)のとおりです。",
"",
"```{r tab.cap='京野菜の出荷量', tab.id='veg', echo=FALSE}",
"kyoto_veg",
"```",
"",
"```{r fig.cap='京野菜の出荷量', fig.id='veg', echo=FALSE}",
"barplot(kyoto_veg$出荷量, names.arg = kyoto_veg$品目, col = \"darkgreen\")",
"```"
)
writeLines(rmd_word, "kyoto_veg.Rmd")
# A4横向き・余白0.8インチ(約2cm)のWordを作成
render("kyoto_veg.Rmd",
output_format = rdocx_document(
# 表と図の番号の付け方
tables = list(caption = list(pre = "表 ", sep = ":")),
plots = list(caption = list(pre = "図 ", sep = ":"), align = "center"),
# 用紙の向きと余白
page_size = page_size(orient = "landscape"),
page_margins = page_mar(top = 0.8, bottom = 0.8, left = 0.8, right = 0.8)
),
quiet = TRUE
)
PowerPointのスライドを作成:rpptx_documentコマンド
「##」の見出しごとに1枚のスライドになります。データフレームはスライドの表に、グラフはスライドの図になります。
| オプション | 意味 | 初期値 |
|---|---|---|
| base_format | 元にする出力形式。bookdown の powerpoint_presentation2 も指定できる | “rmarkdown::powerpoint_presentation” |
| layout | スライドに使うレイアウトの名前 | “Title and Content” |
| master | レイアウトが入っているスライドマスターの名前 | “Office Theme” |
| tcf | 表の条件付き書式。officer::table_conditional_formatting で指定 | list() |
| … | powerpoint_presentation に渡すオプション | なし |
# スライドの中身を書き出す
rmd_pptx <- c(
"---",
"title: \"宇治茶の試飲会\"",
"---",
"",
"## 茶園ごとの評価",
"",
"```{r echo=FALSE}",
"uji_tea",
"```",
"",
"## 香りと渋み",
"",
"```{r echo=FALSE}",
"plot(uji_tea$香り, uji_tea$渋み, pch = 19, col = \"darkgreen\",",
" xlab = \"香り\", ylab = \"渋み\")",
"text(uji_tea$香り, uji_tea$渋み, uji_tea$茶園, pos = 3)",
"```"
)
writeLines(rmd_pptx, "uji_tea.Rmd")
# PowerPointのスライドを作成
render("uji_tea.Rmd",
output_format = rpptx_document(
layout = "Title and Content",
master = "Office Theme"
),
quiet = TRUE
)ブロックを書き出す:knit_print_blockコマンド
officerパッケージで作ったブロックを、Rmdファイルのチャンクの中から文書に書き出します。ループの中など、自動では出力されない場所で使います。チャンクには results=’asis’ を付けます。ここでは産地ごとに、品目を太字の緑にした段落を並べます。
| オプション | 意味 | 初期値 |
|---|---|---|
| x | officerパッケージのブロックのコマンド(fpar、block_toc など)で作ったオブジェクト | なし |
| … | 使われないオプション | なし |
# 産地ごとの段落を書き出す中身
rmd_block <- c(
"---",
"title: \"京野菜の産地\"",
"---",
"",
"```{r results='asis', echo=FALSE}",
"for (i in seq_len(nrow(kyoto_veg))) {",
" knit_print_block(",
" fpar(",
" ftext(kyoto_veg$品目[i], fp_text(bold = TRUE, color = \"darkgreen\")),",
" ftext(paste0(\"(\", kyoto_veg$産地[i], \")\"))",
" )",
" )",
"}",
"```"
)
writeLines(rmd_block, "kyoto_block.Rmd")
# 段落を並べたWordを作成
render("kyoto_block.Rmd", output_format = rdocx_document(), quiet = TRUE)
<おすすめのRに関する書籍です>
ランを書き出す:knit_print_runコマンド
officerパッケージで作ったランを、Rmdファイルのチャンクの中から文書に書き出します。ランは同じ段落の中に続けて入ります。ここでは出荷量が多い品目ほど文字を大きくします。
| オプション | 意味 | 初期値 |
|---|---|---|
| x | officerパッケージのランのコマンド(ftext、run_pagebreak など)で作ったオブジェクト | なし |
| … | 使われないオプション | なし |
# 出荷量で文字の大きさを変える中身
rmd_run <- c(
"---",
"title: \"京野菜の出荷量\"",
"---",
"",
"```{r results='asis', echo=FALSE}",
"for (i in seq_len(nrow(kyoto_veg))) {",
" knit_print_run(",
" ftext(paste0(kyoto_veg$品目[i], \" \"),",
" fp_text(font.size = kyoto_veg$出荷量[i] / 40))",
" )",
"}",
"```"
)
writeLines(rmd_run, "kyoto_run.Rmd")
# 文字の大きさを変えたWordを作成
render("kyoto_run.Rmd", output_format = rdocx_document(), quiet = TRUE)
この記事が誰かの役に立ちますように。