13 チャンクフック (*)

チャンクフックはあるチャンクオプションの値が NULL ではないときに駆動する関数です. チャンクフックを使うと, チャンク内でコードを実行する以上の追加のタスクを実行することができます. 例えばグラフに後処理をしたり (例えば13.1節, 13.2節) , コードチャンクの実行時間を記録したいときなどです. このようなタスクはレポート内の計算や分析に必須でなくても, 例えばグラフを改良したり最も時間のかかるチャンクを特定したりといった, 他の目的に対しては役に立つででしょう.

例えばコンソールになんらかの情報をただ表示するだけなど, チャンクフックをまったく別の作用のために使うことができますし, あるいは返り値を使うなら, それが文字列であれば出力文書にその値を書き出すこともできます.

出力フック (12章参照)のように, チャンクフックは knitr::knit_hooks オブジェクトにて登録されます. 出力フックの名前は knitr によって予約されているので, カスタムチャンクフックに使ってはならないことに注意してください.

names(knitr:::.default.hooks)
##  [1] "source"          "output"         
##  [3] "warning"         "message"        
##  [5] "error"           "plot"           
##  [7] "inline"          "chunk"          
##  [9] "text"            "evaluate.inline"
## [11] "evaluate"        "document"

チャンクフックは同じ名前のチャンクオプションと関連付けられています. 例えば greet という名前のチャンクフックを登録できます.

knitr::knit_hooks$set(greet = function(before) {
  if (before)
    "Hello!" else "Bye!"
})

この後すぐにフック関数の引数について説明します. まずは以下のチャンクでチャンクオプション greet = TRUE を設定してみます.

```{r, greet=TRUE}
1 + 1
```

するとチャンクの前に “Hello!” という文字が現れ, 以下のチャンクの出力部の後に “Bye!” という文字が現れます. これは両者が文字列だからです.

Hello!

1 + 1
## [1] 2

Bye!

チャンクフック関数は beforeoptionsenvirname の4つの引数を取ることができます. 言い換えるならこのような形式にすることができます.

function(before, options, envir, name) {

}

4つの引数はすべてあってもなくてもかまいません. 4つ, 3つ, 2つ, 1つ, あるいは引数がなくとも可能です. 上記の例では before 引数1つだけを使っています. これらの引数は以下のような意味があります.

  • before: このチャンクが現在, 実行される直前か直後かです. チャンクフックはコードチャンクごとに2度実行される, つまり直前に1度 hook(before = TRUE) が, 直後に hook(before = FALSE) が実行されることに注意してください.

  • options: 現在のコードチャンクのチャンクオプションのリストです. 例えば list(fig.width = 5, echo = FALSE, ...) のような値です.

  • envir: チャンクフックが評価される環境です.

  • name: チャンクフックのトリガーとなるチャンクオプションの名前です.

この章の冒頭で言及したように, チャンクフックの返す値が文字列でなければ無視されなにも起こりませんが, 文字列のときは出力文書に書き出されます.