Q&A
What is the is.na() function in R?
Overview
In R, missing data is represented by the special value NA ("Not Available"). Because real-world datasets are full of gaps, detecting and handling NA is a daily task in data analysis. is.na() is the primary tool for detecting them. Crucially, you cannot test for NA with == (e.g. x == NA returns NA, not TRUE), because any comparison involving NA is itself NA. is.na() exists precisely to solve this.
graph LR
A["Vector: c(1, NA, 3, NA, 5)"] --> B["is.na()"]
B --> C["Logical: FALSE TRUE FALSE TRUE FALSE"]
C --> D["Use for: counting,<br/>filtering, imputing"]
style B fill:#1e1b4b,color:#fff
Basic Usage
x <- c(1, NA, 3, NA, 5)
is.na(x)
# [1] FALSE TRUE FALSE TRUE FALSE
It returns a logical vector the same length as the input. This vectorized result is the building block for everything else.
Counting missing values
Because TRUE counts as 1 and FALSE as 0, sum() over the logical vector counts the NAs:
sum(is.na(x)) # 2 -> number of NAs
mean(is.na(x)) # 0.4 -> proportion of NAs
Filtering out missing values
Negate with ! to keep only the non-missing values:
x[!is.na(x)] # 1 3 5
Replacing (imputing) missing values
x[is.na(x)] <- 0 # replace NAs with 0
x # 1 0 3 0 5
With Data Frames
is.na() works element-wise across an entire data frame, returning a logical matrix:
df <- data.frame(a = c(1, NA, 3), b = c("x", "y", NA))
is.na(df)
# a b
# [1,] FALSE FALSE
# [2,] TRUE FALSE
# [3,] FALSE TRUE
colSums(is.na(df)) # NAs per column: a=1, b=1
This pattern - colSums(is.na(df)) - is one of the most common ways to profile missingness in a dataset.
Related Functions
| Function | Purpose |
|---|---|
is.na(x) |
Logical test for NA (and NaN) |
na.omit(x) |
Returns the object with NA rows removed |
complete.cases(df) |
TRUE for rows with no NA in any column |
anyNA(x) |
Fast check whether any NA exists |
is.nan(x) |
Tests specifically for NaN (a subset of NA for is.na) |
coalesce() (dplyr) |
Replace NA with a fallback value |
na.omit(x) # drop NAs
df[complete.cases(df), ] # keep only fully-complete rows
anyNA(x) # TRUE
Important Subtleties
is.na()also returnsTRUEforNaN(Not a Number), sinceNaNis a special kind of missing. Useis.nan()to distinguish.- Never use
== NA- it yieldsNA, neverTRUE. This is a classic beginner bug. - Type-specific
NAs exist (NA_integer_,NA_real_,NA_character_) butis.na()detects them all. - For factors and dates,
is.na()still works element-wise.
NA == NA # NA (NOT TRUE!)
is.na(NA) # TRUE (correct way)
is.na(NaN) # TRUE
is.nan(NaN) # TRUE
is.nan(NA) # FALSE
Why This Matters in Interviews
Data-science interviews frequently probe missing-data handling. Know why == NA fails (every NA comparison is NA), how to count and filter missingness, and the distinction between is.na() and is.nan(). The colSums(is.na(df)) idiom for profiling a dataset is a practical detail worth volunteering.
Common Pitfalls
- Testing equality against
NAwith==instead ofis.na(). - Forgetting
is.na()also flagsNaN. - Dropping rows with
na.omit()when imputation would preserve more data. - Assuming
NAandNULLare the same -NULLis the absence of a value entirely, not a missing one.
References
- R documentation for
NA: https://stat.ethz.ch/R-manual/R-devel/library/base/html/NA.html - R for Data Science (Wickham & Grolemund): https://r4ds.hadley.nz/