引数名の部分マッチにより意図しない引数に値が渡ることがある
Rの名前付き引数は、他の引数名と衝突しない範囲で省略して書けます(部分マッチ)。似た名前の引数が複数ある関数で省略して書くと、意図と違う引数に値が渡ってしまうことがあります。
エラーメッセージの読み方
Error in resize(10, w = 2) : argument 2 matches multiple formal arguments
Error- エラー種別 — 実行中に発生しました
resize(10, w = 2)- 発生箇所 — エラーの原因になった呼び出し
argument 2 matches multiple formal arguments- 詳細メッセージ — 何が問題だったか
このエラーが出る典型パターン
パターン1
1 resize <- function(width, weight = 1) { 2 width * weight 3 } 4 result <- resize(10, w = 2) ^ 5 cat(result, "\n")
widthとweightはどちらも"w"で始まるため、w=2は部分マッチが曖昧になりエラーになります。weのように候補が1つに絞れる長さまで書く必要があります。
直し方: w を we にします。
パターン2
1 adjust <- function(base, bonus = 1) { 2 base + bonus 3 } 4 result <- adjust(10, b = 5) ^ 5 cat(result, "\n")
baseとbonusはどちらも"b"で始まるため、b=5はどちらの引数を指しているか一意に決まらずエラーになります。
直し方: b を bo にします。
パターン3
1 scale_up <- function(size, spacing = 1) { 2 size + spacing 3 } 4 result <- scale_up(10, s = 3) ^ 5 cat(result, "\n")
sizeとspacingは両方"s"で始まるため、s=3では候補が2つに絞れずエラーになります。
直し方: s を sp にします。
パターン4
1 trim_text <- function(text, trim_end = 0) { 2 nchar(text) - trim_end 3 } 4 result <- trim_text("hello", t = 2) ^ 5 cat(result, "\n")
textとtrim_endはどちらも"t"で始まるため、t=2は部分マッチが曖昧になってしまいます。
直し方: t を tr にします。
パターン5
1 compute_total <- function(delta, discount = 0) { 2 delta - discount 3 } 4 result <- compute_total(100, d = 20) ^ 5 cat(result, "\n")
deltaとdiscountはどちらも"d"で始まるため、d=20という省略形は候補が絞れずエラーになります。
直し方: d を di にします。
よくある誤解
「省略して書いた引数名は、一番近い名前に自動でマッチしてくれるから安全なはず」という思い込みは誤りです。部分マッチは「他に候補が無ければ」成立する仕組みで、似た名前の引数が増えると、どちらにマッチするかがコードの見た目だけでは分かりにくくなります。
実務での勘所
Rの引数のマッチングは、3段階の決まった手順で行われます。まず名前が完全に一致するものを先に確定させ、次に残っている名前付き引数の中で部分マッチが使えるものを確定させ、最後に名前の付いていない引数を残ったパラメータへ順番通りに当てはめます。この手順を知らずに部分マッチに頼ると、後から関数に似た名前の引数が追加された途端、完全一致だった呼び出しの解釈が変わってしまう可能性があります。実務では、よほど短い決まりきった呼び出しでない限り、引数名は省略せずフルに書くほうが安全です。