Rの可変引数(…)
Rでも関数は可変引数を持つことができます。よく使われる関数が可変長なので存在は広く知られていますが、入門的な文法解説では関数の宣言や関数内で引数の値を調べる方法の説明は割愛されることが多いようです。しかし、汎用性の高い関数をつくるときには便利な機能なので覚えておきましょう。
1 可変引数のヘルプ
ヘルプを見ればだいたい説明があるわけですが、ダブルコーテーションを付け忘れないように注意しましょう。
"..." ?
2 可変引数の関数の作成
名前が決まった変数を並べた後に...
を書くだけです。
<- function(n, ...){
func_va print(...elt(n)) # 可変引数のn番目を表示
print(..1) # 可変引数の1番目を表示
print(..2) # 可変引数の2番目を表示
print(list(...)) # リストにして表示
}func_va(3, "a", "b", "c")
[1] "c"
[1] "a"
[1] "b"
[[1]]
[1] "a"
[[2]]
[1] "b"
[[3]]
[1] "c"
...
の後に名前が決まった変数を書いても宣言できますが、デフォルト値を設定しておかないと...
の中に引数が入ってしまうので、名前がある変数に値が入りません。
<- function(..., n) print(m)
func_wrong func_wrong("a", "b", 1)
オブジェクト ``m`` がありません
とエラーが出ます。
3 関数のラッパーをつくる
応用例として、do.call
と組み合わせて関数のラッパーをつくることができます。
read.table
の引数にfileEncoding
が無ければ付け加えるとすると、以下のようになります。
<- function(...){
read.table # 可変長引数をリストに展開
<- list(...)
args # fileEncodingが存在しなければ、UTF-8をセット
if(!("fileEncoding" %in% names(args))){
<- append(args, list("fileEncoding"="UTF-8"))
args
}# ホンモノのread.tableを呼び出す
# package:utils はホンモノがあるEnvironment
do.call(get("read.table", env=as.environment("package:utils")), args)
}
なお、パッケージ内の関数などはグローバル環境を参照せずutils::read.table
を読むので、この方法では誤魔化せないです。