Code Fix

中級

== で NA と比較すると NA が返り FALSE にはならない

NAを含む式を==で比較すると、結果はTRUEでもFALSEでもなくNAになります。「等しくない」ことを確認したいつもりでNAと比較しても、判定自体ができません。

エラーメッセージの読み方

Error in if (value == 5) { : missing value where TRUE/FALSE needed
Error
エラー種別 — 実行中に発生しました
if (value == 5) {
発生箇所 — エラーの原因になった呼び出し
missing value where TRUE/FALSE needed
詳細メッセージ — 何が問題だったか

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

パターン1

 1  value <- NA
 2  if (value == 5  ) {
              ^
 3    cat("skip\n")
 4  } else {
 5    cat("process\n")
 6  }
Error in if (value == 5) { : missing value where TRUE/FALSE needed

NAとの==比較はTRUEでもFALSEでもなくNAになるため、if()の条件に使うとその場でエラーになります。

直し方: value == 5 を is.na(value) にします。

この問題を解いてみる →

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

パターン2

 1  age <- NA
 2  if (age == 20 ) {
             ^
 3    cat("skip\n")
 4  } else {
 5    cat("process\n")
 6  }
Error in if (age == 20) { : missing value where TRUE/FALSE needed

ageがNAのとき==での比較結果もNAになるので、is.na()で先に確認する必要があります。

直し方: age == 20 を is.na(age) にします。

この問題を解いてみる →

パターン3

 1  score <- NA
 2  if (score == 0  ) {
              ^
 3    cat("skip\n")
 4  } else {
 5    cat("process\n")
 6  }
Error in if (score == 0) { : missing value where TRUE/FALSE needed

scoreがNAの場合、0と比較してもFALSEにはならずNAになるため、if()はエラーで止まります。

直し方: score == 0 を is.na(score) にします。

この問題を解いてみる →

パターン4

 1  status <- NA
 2  if (status == "done") {
                ^
 3    cat("skip\n")
 4  } else {
 5    cat("process\n")
 6  }
Error in if (status == "done") { : missing value where TRUE/FALSE needed

文字列との比較でも、statusがNAであれば結果はNAになり、if()の条件としては使えません。

直し方: status == "done" を is.na(status) にします。

この問題を解いてみる →

パターン5

 1  flag <- NA
 2  if (flag == TRUE) {
              ^
 3    cat("skip\n")
 4  } else {
 5    cat("process\n")
 6  }
Error in if (flag == TRUE) { : missing value where TRUE/FALSE needed

論理値同士の比較でも、片方がNAならば==の結果はNAになり、if()には使えません。

直し方: flag == TRUE を is.na(flag) にします。

この問題を解いてみる →

よくある誤解

「NAと比較すればFALSEになって、if文で安全に弾けるはず」という思い込みは誤りです。NAとの比較結果は常にNAで、if()の条件に使うとエラーになります。NAかどうかを調べたい場合はis.na()を使う必要があります。

実務での勘所

同じ「値が含まれているか」を調べる操作でも、%in%は==と違ってNAを賢く扱います。NA %in% c(1, 2, NA)はTRUEになり、NA %in% c(1, 2, 3)はFALSEになります。%in%は常に明確なTRUE/FALSEを返し、NAを1つの特別な値として律儀に照合してくれるためです。「NAが含まれているかどうか」を調べたいだけなら、==で比較してNAが返ってくることに悩むより、is.na()や%in%を使うほうが素直に答えが得られます。

演習をはじめる

関連するエラー

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