Code Fix

初級

ベクトルの範囲外アクセスはエラーにならず NA を返す

存在しない添字でベクトルにアクセスしても、Rはエラーを出さずNAを返すだけです。その後NAを使った計算をすると、結果全体がNAとして伝播します。

なぜエラーが出ないのか

出力: NA
(エラーなし)
Rは何も報告しません。文法としても実行としても正しいコードだからです
NA
実際の出力 — 期待した結果と食い違っている箇所

このエラーが出る典型パターン

パターン1

 1  nums <- c(1, 2, 3)
 2  print(nums[10])
                ^
出力: NA

存在しない添字でベクトルにアクセスしても例外にはならず、Rは黙ってNAを返します。

直し方: 10 を 1 にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  fruits <- c("apple", "banana")
 2  print(fruits[5])
                 ^
出力: NA

配列の要素数を超えた添字を指定しても、エラーにならず結果はNAになります。

直し方: 5 を 1 にします。

この問題を解いてみる →

パターン3

 1  scores <- c(70, 80, 90)
 2  print(scores[100])
                  ^
出力: NA

範囲外アクセスで即座に例外が飛ぶ言語の感覚のままだと、このNAの静かな発生に気づけません。

直し方: 100 を 3 にします。

この問題を解いてみる →

パターン4

 1  names <- c("A", "B", "C")
 2  print(names[9])
                ^
出力: NA

添字が範囲内かどうかは、ベクトルの要素数(length)と照らし合わせて確認する必要があります。

直し方: 9 を 1 にします。

この問題を解いてみる →

パターン5

 1  data <- c(1, 2)
 2  print(data[7 ])
                ^
出力: NA

このNAが後続の計算に紛れ込むと、ずっと後の行で初めて計算結果全体がNAになって表面化します。

直し方: 7 を 1 にします。

この問題を解いてみる →

よくある誤解

「範囲外にアクセスすればすぐエラーで止まるはず」という他言語の感覚は通用しません。Rのベクトルは[ ]による範囲外アクセスでも黙ってNAを返すため、異常に気づくのはずっと後になることがあります。

実務での勘所

NAは計算に混ざると、結果全体を「汚染」しながら伝播します。NA * 0は0になりそうに思えますが、実際にはNAのままです(「分からない数に0を掛けても、分からないままだ」という統計的に厳密な扱いです)。sum(c(1, 2, NA, 4))のように合計を取る関数も、NAが1つでも含まれていれば結果全体がNAになります(na.rm = TRUEを指定しない限り)。範囲外アクセスで紛れ込んだ1つのNAが、後で行う集計や平均の計算全体を静かに壊してしまうのは、この伝播の仕組みのためです。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)