2018/3/2の第68回TokyoRに参加してきました。
その懇親会でniszetさんとigjitさんとお話し、関数のヘルプ見る時?関数という書き方は面倒だよねという話をしました。
できたら関数?という書き方をしたいけど多分無理だよね、という話をしていました。
無理ゲーと思いつつ、RStduioなら左右のペーンを利用してヘルプと同時に関数のソースも見たいと要望は募るばかり。
そんなfunction help略してfelpパッケージに挑戦しようという話になりました。
雛形
関数のヘルプを見るにはhelp、ソースを見るにはprint.functionを用います。
後者は所謂総称的関数printのmethodの一つ(S3 generic)です。
これらを組合せればヘルプとソースを同時に見るfelp関数を作れるはず。
出来上がったのが以下。
felp <- function(x, ...) {
base::print(help(deparse(substitute(x)), ...))
base::print.function(x, ...)
}
このfelp関数を用い、
felp(help)
とすれば、helpのソースとヘルプを同時に見る事ができます。
ポイントは4点。
-
felp(x)のxを非標準評価する-
help(x)とすると、xという名前の関数のヘルプを探してしまう。 -
help(deparse(substitute(x)))ならOK
-
-
helpを明示的にprintする-
helpをprintの中に入れないと、ヘルプは表示されずソースコードしか見れません。 - これはRにおいては関数内で実行された結果の内、自動に
printされるのは最後に実行された行のみだからです。
-
-
print.functionはbase::print.functionとし、出自を明らかにする- 雛形段階では重要ではありません。
- 最終的に
print.functionを新たに定義してマスクし、関数と打つだけでヘルプとソースを見るための布石です。
-
...を使うことで、helpやprint.functionに引数を適宜パスする- これにより、
felp(select, package = 'MASS')といった具合にどのパッケージの関数についてヘルプを見たいか、選択できるようになります。 - ただし、雛形段階ではソースを表示する関数がどのパッケージ由来かを選ぶことができません(最も近い環境のものが選ばれる)。
- これにより、
発展させたいが……!
さて、print.function <- felpとすると、helpと入力するだけで、helpのヘルプとソースが呼び出されるようになりそうです。
しかし、実際にはこれはうまく行きません。
No documentation for ‘x’ in specified packages and libraries:
you could try ‘??x’
という文字列の後にhelpのソースが表示され、ヘルプが表示されないのです。
その原因には心当たりがあります。2018/03/03 13:13 以下は勘違いでした。原因は根深そうです。print(x = help)はちゃんと動きます。もっと問題は根深そうです。yutanihilationさん、ご指摘ありがとうございます。
S3 genericを利用しているため、helpを入力した時、実行されているコードは以下です。
print(x = help)
この時helpはfunctionですので、適したmethodとしてprint.functionを呼び出し、その引数xにxを与えます。
print.function(x = x)
結果、現在の実装では、deparse(substitute(x))の部分が"x"を返します。
しかしながら、xだなんて関数は定義されていtopicはないよと怒られるわけです。
仕様の壁にぶちあたった気がしますが、うまい回避法があれば、ご提案下さい。
2018/03/03 11:25
helpの第一引数はtopicなので、「xだなんて関数は定義されていない」というのは実態に即していないとの指摘をyutanihilationさんから頂き、「topicはない」に修正しました。
ご指摘ありがとうございます。