Other Errors

Missing value in condition

Matches: missing value where TRUE\/FALSE needed

WHAT THIS ERROR MEANS

An if statement or while loop received NA instead of TRUE or FALSE. This happens when the condition evaluates to a missing value.

WHY IT HAPPENS — 4 COMMON CAUSES

1. The variable being tested is NA

Any comparison involving NA returns NA, not FALSE. NA > 0 is NA, and if() cannot branch on that. This is deliberate: R does not know whether the missing value exceeds zero, so it refuses to guess.

2. A lookup returned nothing

Indexing a vector with a name that is not there, or matching a value that does not exist, yields NA. If that result feeds straight into a condition, the branch fails rather than taking the else path.

3. A coercion silently produced NA

as.numeric("abc") gives NA with a warning. If the condition tests that result, the failure surfaces at the if() rather than at the conversion, several lines from the real cause.

4. A function returned NA for an all-NA input

mean(x) with any NA in x returns NA unless na.rm = TRUE. Feeding that into a threshold test moves the error downstream of the real problem.

HOW TO DIAGNOSE WHICH ONE IT IS

  1. Print the condition’s value on its own line before the if(). Seeing NA rather than TRUE/FALSE confirms it immediately.
  2. Check the input with is.na(x) and sum(is.na(df$col)) to see how widespread the missingness is.
  3. Use traceback() straight after the error to find which call produced the NA.
  4. For aggregate functions, test whether adding na.rm = TRUE changes the result — if it does, missing data is your cause.
  5. In a loop, print the index alongside the value so you can see which iteration breaks.

HOW TO FIX IT

1. Check if your condition variable contains NA.

2. Use is.na() to handle missing values.

3. Add na.rm = TRUE to functions like any() or all().

CODE EXAMPLES

BAD — THIS CAUSES THE ERROR
x <- NA
if (x > 0) print("positive")
GOOD — CORRECT APPROACH
x <- NA
if (!is.na(x) && x > 0) print("positive")

MORE SCENARIOS THAT TRIGGER THIS

Guarding a possibly-missing value

BAD
if (df$score[i] > 50) {
  flag <- "pass"
}
# Error when score is NA
GOOD
if (!is.na(df$score[i]) && df$score[i] > 50) {
  flag <- "pass"
}

The && operator short-circuits: if the left side is FALSE it never evaluates the right, so the comparison never sees the NA. Using & instead would evaluate both sides and fail.

Vectorised conditions do not have this problem

BAD
df$band <- if (df$score > 50) "high" else "low"
# condition has length > 1, and NAs break it
GOOD
df$band <- ifelse(is.na(df$score), NA_character_,
                  ifelse(df$score > 50, "high", "low"))

# or, clearer with dplyr:
df <- df |> mutate(band = case_when(
  is.na(score) ~ NA_character_,
  score > 50   ~ "high",
  .default     = "low"
))

if() takes a single value; for a whole column use ifelse() or case_when(), both of which propagate NA per element rather than erroring.

PACKAGE-SPECIFIC NOTES

As of R 4.2 an if() condition of length greater than one is an error rather than a warning, so vectorised conditions now fail loudly — use ifelse() or dplyr::case_when() for column-wise logic. isTRUE(x) is a useful guard because it returns FALSE for NA, NULL and non-logical input instead of raising, which makes it well suited to defensive checks where any non-TRUE value should take the else branch. dplyr::coalesce(x, 0) substitutes a default for NA before the comparison ever happens.

FUNCTIONS WORTH KNOWING

is.na()ifelse()dplyr::case_when()dplyr::coalesce()isTRUE()any()complete.cases()

FREQUENTLY ASKED QUESTIONS

Why does NA > 0 return NA instead of FALSE?

NA means the value is unknown, so the comparison genuinely has no answer — the true value might or might not exceed zero. Returning FALSE would assert something R cannot know. This propagation is consistent across arithmetic and comparison operators.

Should I use && or & inside if()?

&& inside if(), because it takes single values and short-circuits, which is what lets !is.na(x) && x > 0 work. & is vectorised and evaluates both sides, so it belongs in ifelse() and filter() rather than in if().

How do I treat NA as FALSE throughout a condition?

Wrap it in isTRUE(), which returns FALSE for anything that is not a single TRUE. In dplyr, filter() already drops NA rows, and tidyr::replace_na() sets an explicit default before the test.

Still stuck?

Paste your code in RChat and the AI will fix this error in context.

Try RChat Free →

RELATED R ERRORS