階層化するモチベーションはどこにあるのかということで。
さて、RMarkdownの階層化の話の続きです。
RMarkdown、基本的には1つのファイルに収めておいた方があっちこっち見に行かなくて良い分、管理は楽になります。
しかし、コード1000行を超えてくるあたり1で厳しさを感じるようになります。
特に、同じような図を作成するようなケースではコードのコピペが横行しがち2で、ちょっとしたフォーマットをいじるときにも数十か所を頑張って修正するという苦行が発生したりします。
よく言われるように、同じコードが3回出てきたらまとめましょう。Rのコードなら関数、関数のまとまりならパッケージ、RMarkdownのチャンクなら階層化したRMarkdown、といった感じですね。
さて、実際にやってみます。前回からちょっと変えています。まずはiris_child.Rmd
の方。
--- title: "plot iris in RMarkdown with params" author: "niszet" date: "`r Sys.Date()`" output: html_document params: x: "Sepal.Length" --- /```{r setup, include=FALSE} library(tidyverse) library(ggridges) /``` ## plot of `r params$x` /```{r echo=FALSE, message=FALSE} iris %>% ggplot()+geom_density_ridges( aes_string(x=params$x,y="Species", fill= "Species", point_color="Species", point_fill="Species"), position="raincloud", jittered_points=TRUE, alpha=0.3, scale=0.4)+ theme_bw() /```
次に親の方ですが、iris_parent.Rmd
というファイル名で
--- title: "plot iris in hierarchical RMarkdown with params" author: "niszet" date: "`r Sys.Date()`" output: html_document --- /```{r setup, include=FALSE} knitr::opts_chunk$set(echo = TRUE) options(knitr.duplicate.label = 'allow') /``` # Plots of iris {.tabset} /```{r echo=FALSE, message=FALSE} envir <- new.env(parent = parent.frame()) envir$params <- NULL out <- NULL xs <- c("Sepal.Length", "Petal.Length", "Sepal.Width", "Petal.Width") for (xx in xs){ envir$params$x <- xx out <- c(out, knitr::knit_child("iris_child.Rmd", envir=envir, quiet=TRUE)) } knitr::asis_output(out) /```
のようにしてみます。前回との違いは、呼び出し側でfor
のループがあります。で、envir$params$x
に"Sepal.Length", "Petal.Length", "Sepal.Width", "Petal.Width"
を順に送り込んでいます。
また、親の方にh1
のレベルでPlots of iris
と書いて、tabsetの指定をしています。これは
にあるように、#
のレベルで見て下位のレベルのセクションをタブ化してくれるというものです。これは実物を見た方がわかりやすい。
そんなわけで、親RmdでKnitしますと、
とか、
こんな感じに。
タブを選択して、それぞれの図が表示されているのがわかるでしょうか?このタブはrmarkdown
パッケージが入っていないとダメらしいですが、まぁRMarkdown書いている人は多分入ってるよね…。
これにtoc
やtoc_float
、theme
などを設定するとすごい簡単にシャレオツレポートの完成です。逆に言えば、そういう見た目に騙されてはいけないよ…ということですね。
ちなみに、これらのキャプチャ画像は手でやってしまっているので、再現可能性もへったくれもないです。すみません…。webshot
使えばいいんですけどね…ブログなので許してください、ということで。
Enjoy!!