14.1 コードチャンクを再利用する
コードチャンクは, コピーアンドペーストなしで文書のどの場所でも自由に再利用できます. ポイントはコードチャンクにラベルを付けることで, そうすると他の場所でラベルによって参照することができます. コードチャンクの再利用には3種類の方法があります.
14.1.1 チャンクを別の場所にも埋め込む (*)
あるコードチャンクは, チャンクのラベル名を <<>>
で囲んで別のコードチャンクに埋め込むことができます. すると knitr は自動的に <<ラベル>>
を実際のコードへと展開してくれます. 例えば, この方法で R 関数を作ることができます.
華氏温度を摂氏温度に変換する関数を定義する
```{r, f2c}
F2C <- function(x) {
<<check-arg>>
<<convert>>
}
```
最初に入力値が数値か確認する
```{r, check-arg, eval=FALSE}
if (!is.numeric(x)) stop("入力は数値でなければなりません!")
```
それから実際に変換します
```{r, convert, eval=FALSE}
(x - 32) * 5/ 9
```
これはドナルド=クヌースの提案する文芸プログラミング の主要なアイディアの1つに基づいたものです. この技術の利点は (複雑な) コードを小さな部品に分割し, 別々のコードチャンクに書き, 文脈の中で説明することができる点です. 全ての部品は実行される主要なコードチャンクで構成することができます.
上記の例に対して, f2c
というラベルのある最初のコードチャンクはこうなります.
```{r, f2c}
F2C <- function(x) {
if (!is.numeric(x)) stop("The input must be numeric!")
(x - 32) * 5/ 9
}
```
1つのコードチャンクには好きな数のコードチャンクを埋め込むことが可能です. 埋め込みは再帰的にすることも可能です. 例えば, チャンク A をチャンク B に埋め込み, さらにチャンク B をチャンク C に埋め込むこともできます. チャンク C はチャンク B から読み込まれたチャンク A を含むことになります.
マーカー <<ラベル>>
は独立した行に置く必要はありません. コードチャンクのどこにでも埋め込むことができます.
14.1.2 別のチャンクで同一のチャンクラベルを使う
完全に同じコードチャンクを2回以上使いたいならば, ラベル付きのチャンクを定義し, さらに同じラベルで中身が空のチャンクを作ることもできます. 例えばこのように.
これは評価されないコードチャンクです
```{r, chunk-one, eval=FALSE}
1 + 1
2 + 2
```
実際に評価されるのはこちらです
```{r, chunk-one, eval=TRUE}
```
上記の例でチャンクラベル “chunk-one” を2度使っており, 2度目のチャンクは最初のチャンクの単なる再利用です.
グラフないしは他のファイルを生成するのに, この方法で複数回コードチャンクを実行するのはお薦めしません. 後のチャンクで作成された画像ファイルがそれ以前のものを上書きするかもしれないからです. これらのチャンクのうち1つだけにチャンクオプション eval = TRUE
を使い, それ以外では eval =FALSE
を使うのならば大丈夫です.
14.1.3 参照ラベルを使う (*)
チャンクオプション ref.label
はチャンクラベルのベクトルを取り, そのチャンクの中身を取得できます. 例えば以下の chunk-a
というラベルのコードチャンクは chunk-c
と chunk-b
を結合したものです.
```{r chunk-a, ref.label=c('chunk-c', 'chunk-b')}
```
```{r chunk-b}
# これはチャンク b
1 + 1
```
```{r chunk-c}
# これはチャンク c
2 + 2
```
言い換えるなら, chunk-a
は本質的にこうなります.
```{r chunk-a}
# これはチャンク c
2 + 2
# これはチャンク b
1 + 1
```
チャンクオプション ref.label
のあるおかげで, コピーアンドペーストを使うことなくコードチャンクをとても柔軟に再構成することができます. 参照先のコードチャンクが ref.label
が使われたチャンクの前にあるか, 後にあるかは問題になりません. 先に書かれたコードチャンクは後のコードチャンクを参照できます.
4.19節にはこのチャンクオプションの応用例があります.