12.1 ソースコードを検閲する
ときにはレポートにソースコードの全文を掲載したくないこともあるでしょう. 例えばコードのある行にパスワードが書かれているかもしれません. 11.7節ではチャンクオプション echo で R コードの文ごとに表示の有無を選べることを言及しました. 例えば echo = 2 で2つ目の文を表示します. この節では, コードのインデックスを指定する必要のない, より柔軟な方法を提供します.
基本的なアイディアはコードに特殊なコメント, 例えば # 秘密!! のようなものを追加するということです. このコメントがコードのある行から検出されると, 行を省略します. 以下は source フックを使用した完全な例です.
---
title: "`source` フックを使用してコードのある行を隠す"
---
初めに, 末尾に `# 秘密!!` という文字列を含むコードの行を排除する `source` フックを用意します.
```{r, include=FALSE}
local({
hook_source <- knitr::knit_hooks$get('source')
knitr::knit_hooks$set(source = function(x, options) {
x <- x[!grepl('# 秘密!!$', x)]
hook_source(x, options)
})
})
```
これで新しいフックをテストできます. この文書を knit すると, 特殊なコメント `# 秘密!!` のある行が見えなくなります.
```{r}
1 + 1 # 表示されるべき通常のコード
# 実際のユーザー名とパスワードを使ってみてください
auth <- httr::authenticate("user", "passwd")
auth <- httr::authenticate("yihui", "horsebattery") # 秘密!!
httr::GET("http://httpbin.org/basic-auth/user/passwd", auth)
```上記の source フックの重要な部分はこの行です. これはソースコードの入ったベクトル x から grepl() で追跡用のコメントの # 秘密!! とマッチングしたものを排除しています.
正確に言うなら, 上記のフックは追跡用の # 秘密!! というコメントのある行ではなく, 評価式 (expressions) を全て排除します. x は実際には R 評価式のベクトルだからです. 例えば以下のコードチャンクを考えます.
source フック内の x の値はこうなります.
R 評価式ではなく行単位で隠したいなら, x を行ごとに分割しなければなりません. xfun::split_lines() の使用を検討するとよいでしょう. フック関数の本体はこうなります.
x <- xfun::split_lines(x) # 個別の行に分割する
x <- x[!grepl("# SECRET!!$", x)]
x <- paste(x, collapse = "\n") # 結合して1つの行にする
hook_source(x, options)この例はソースコードの文字列を操作する方法を, そして grepl() は決して文字列操作の唯一の方法ではない, ということを示しています. 12.2節では他の例もお見せしています.