Understanding NA in R
Learn what NA means, why it propagates, and how it differs from NULL.
Understanding NA in R is a free R Academy lesson on CoddyKit. This is lesson 1 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the R Academy learning path, and your progress syncs across the web and the CoddyKit app. The R Academy course includes 4 lessons in total.
What is NA in R?
NA stands for Not Available — it represents a missing or unknown value. Unlike NULL (absence of an object) or NaN (not a number), NA is a placeholder for data that exists but is unknown.
# NA represents a missing value
height_cm <- c(175, NA, 162, 188, NA, 170)
cat('Heights:', height_cm, '
')
cat('Length:', length(height_cm), '
') # NA counts as an element
cat('Sum:', sum(height_cm), '
') # NA propagatesNA vs NULL
NA is a missing value inside a vector — the slot exists but has no known value. NULL is the absence of an object entirely — it has length 0 and cannot be stored inside a vector.
# NA: element exists, value unknown
vec_with_na <- c(1, NA, 3)
cat('Vector with NA, length:', length(vec_with_na), '
') # 3
# NULL: nothing there at all
vec_with_null <- c(1, NULL, 3)
cat('Vector with NULL, length:', length(vec_with_null), '
') # 2!
# NULL gets dropped; NA is kept
cat('vec_with_na:', vec_with_na, '
')
cat('vec_with_null:', vec_with_null, '
')NA vs NaN
NaN (Not a Number) results from mathematically undefined operations like 0/0 or sqrt(-1). It is a special numeric value, while NA is a general missing value marker that can apply to any type.
# NaN from undefined operations
cat('0/0 =', 0/0, '
') # NaN
cat('sqrt(-1) =', sqrt(-1), '
') # NaN (with warning)
cat('Inf - Inf =', Inf - Inf, '
') # NaN
# NaN IS also NA (a special case)
cat('is.nan(NaN):', is.nan(NaN), '
')
cat('is.na(NaN): ', is.na(NaN), '
') # TRUE!
cat('is.nan(NA): ', is.nan(NA), '
') # FALSENA vs Inf
Inf and -Inf represent positive and negative infinity — they result from operations like 1/0. Unlike NA, Inf is a known (if extreme) numeric value and participates normally in comparisons.
cat('1/0 =', 1/0, '
') # Inf
cat('-1/0 =', -1/0, '
') # -Inf
cat('Inf + 1 =', Inf + 1, '
') # Inf
cat('Inf > 1000:', Inf > 1000, '
') # TRUE
cat('is.infinite(Inf):', is.infinite(Inf), '
')
cat('is.na(Inf): ', is.na(Inf), '
') # FALSENA Propagation in Arithmetic
NA is contagious in arithmetic: any operation involving NA returns NA. This is intentional — if one value in a computation is unknown, the result is also unknown.
x <- NA
cat('NA + 5: ', x + 5, '
') # NA
cat('NA * 0: ', x * 0, '
') # NA (not 0!)
cat('NA == NA:', x == NA, '
') # NA (not TRUE!)
cat('NA > 5: ', x > 5, '
') # NA
cat('sum(1,NA):', sum(1, NA), '
') # NAtypeof(NA) — Typed NAs
The default NA has type logical. R provides typed NA variants for each atomic type. These are important when working with typed vectors to avoid unintended type coercion.
cat('typeof(NA): ', typeof(NA), '
') # logical
cat('typeof(NA_integer_): ', typeof(NA_integer_), '
') # integer
cat('typeof(NA_real_): ', typeof(NA_real_), '
') # double
cat('typeof(NA_complex_): ', typeof(NA_complex_), '
') # complex
cat('typeof(NA_character_):', typeof(NA_character_), '
') # characterNA_integer_ in Practice
When creating an integer vector with a missing value, use NA_integer_ to keep the vector type clean. Using plain NA causes implicit coercion to double in some contexts.
# Using plain NA in an integer vector
v1 <- c(1L, 2L, NA, 4L)
cat('typeof with NA: ', typeof(v1), '
') # integer (OK here)
# Explicit typed NA is safer in functions
v2 <- c(1L, 2L, NA_integer_, 4L)
cat('typeof with NA_integer_:', typeof(v2), '
') # integer
# Check they behave the same
cat('Same?', identical(v1, v2), '
')NA_real_ and NA_character_
NA_real_ is used for missing values in double (numeric) vectors, and NA_character_ for missing strings. These are especially important when building vectors inside functions where type consistency matters.
# Character vector with missing
names_vec <- c('Alice', 'Bob', NA_character_, 'Dave')
cat('Names:', names_vec, '
')
cat('typeof:', typeof(names_vec), '
')
# Numeric with missing
readings <- c(22.5, NA_real_, 21.3, NA_real_, 24.1)
cat('Readings:', readings, '
')
cat('Non-NA count:', sum(!is.na(readings)), '
')NA in Logical Operations
NA in logical operations follows three-valued logic: TRUE | NA is TRUE (because TRUE OR anything is TRUE), but FALSE | NA is NA (we cannot determine the result without knowing NA's value).
cat('TRUE | NA:', TRUE | NA, '
') # TRUE
cat('FALSE | NA:', FALSE | NA, '
') # NA
cat('TRUE & NA:', TRUE & NA, '
') # NA
cat('FALSE & NA:', FALSE & NA, '
') # FALSE
# Never use == to test for NA!
cat('NA == NA:', NA == NA, '
') # NA (not TRUE!)
cat('is.na(NA):', is.na(NA), '
') # TRUE (correct way)NA in Vectors and Data Frames
Missing values appear frequently in real-world data. Understanding how NA behaves helps you correctly interpret summaries, spot data quality issues, and choose the right handling strategy.
ages <- c(25, NA, 32, NA, 29, 41, NA, 35)
cat('Ages:', ages, '
')
cat('Length:', length(ages), '
')
cat('Missing count:', sum(is.na(ages)), '
')
cat('Present count:', sum(!is.na(ages)), '
')
cat('Mean (fails):', mean(ages), '
') # NA
cat('Mean (works):', mean(ages, na.rm = TRUE), '
') # 32.4NA Types: A Complete Picture
Here is a summary of the NA-related special values in R:
NA— generic missing value (logical type)NA_integer_,NA_real_,NA_complex_,NA_character_— typed NAsNaN— undefined number (result of 0/0, sqrt(-1))Inf,-Inf— infinite values (result of 1/0)NULL— absence of an object (length 0)
# Test functions for special values
x <- c(1, NA, NaN, Inf, -Inf, 0)
cat('Values: ', x, '
')
cat('is.na(): ', is.na(x), '
') # TRUE for NA and NaN
cat('is.nan(): ', is.nan(x), '
') # TRUE only for NaN
cat('is.infinite(): ', is.infinite(x), '
') # TRUE for Inf and -Inf
cat('is.finite(): ', is.finite(x), '
') # TRUE only for normal numbersQuick Check
What does NA == NA evaluate to in R?
Recap: Understanding NA
Excellent! Key takeaways from this lesson:
NA= missing value (known to exist but value unknown)NULL= absence of an object (dropped from vectors)NaN= undefined arithmetic result (is also NA)Inf/-Inf= infinite values (are NOT NA)- NA is contagious in arithmetic — operations on NA return NA
- Use typed NAs (
NA_integer_, etc.) for type-safe code - Always test for NA with
is.na(), never with== NA
# Key tests side by side
special_vals <- list(NA=NA, NaN=NaN, Inf=Inf, 'NULL-in-vec'=c(1,NULL,3)[2])
for (name in names(special_vals)) {
v <- special_vals[[name]]
cat(name, '| is.na:', is.na(v), '| is.nan:', is.nan(v[!is.infinite(v)]), '
')
}Learn R with an AI tutor — free
Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.
- Courses
- 43
- Lessons
- 159
Frequently Asked Questions
Is the “Understanding NA in R” lesson free?
Yes — any 3 lessons of the R Academy learning path, including “Understanding NA in R”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The R Academy course includes 4 lessons in total.
What will I learn in “Understanding NA in R”?
Learn what NA means, why it propagates, and how it differs from NULL. You practise R Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start R Academy?
No prior experience is required. R Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 1 of 4.
How long does the “Understanding NA in R” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this R Academy lesson?
Yes. Every R Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Understanding NA in R
- Detecting and Counting Missing Values
- Removing and Replacing NA Values
- NA in Calculations and Aggregations