Written and maintained by CASRAI Editorial Board
Last updated
To replace NA with 0 in R, use replace_na(x, 0) from tidyr on a vector or a column, or coalesce(x, 0) from dplyr. For a whole data frame in base R, assign into the positions that is.na() flags: df[is.na(df)] <- 0. The same steps answer “replace na with 0 in r” however you spell it. The part most guides skip is deciding whether 0 is the right value, covered below.
What it is used for in research
R marks a missing value with NA. Models, sums and means treat it differently from a number, so analysts often replace it before computing. Replacing NA with 0 is legitimate when a missing entry really means “none recorded” or a count of zero. When the value is unknown, 0 is a real number that enters every later calculation, so leaving the NA, or choosing a deliberate missing-data method, is usually safer. The CASRAI guide to data cleaning steps places this decision in the wider cleaning workflow, and listwise vs pairwise deletion covers the alternative of leaving NAs out of the calculation.
What counts as missing in R
According to the R documentation for NA (checked 2026-10-29), NA is a logical constant of length 1 that contains a missing-value indicator, and typed versions exist: NA_integer_, NA_real_, NA_complex_ and NA_character_. A character NA is not the same as the text string “NA”. is.na() returns a logical vector of the same length as its input, TRUE for NA, and NaN also counts as missing for numeric and complex data. Applied to a data frame, it returns a logical matrix with the data frame’s dimensions.
The N/A spelling
R’s missing value is written NA, not N/A. If a file contains the text “N/A”, it arrives as an ordinary string unless you tell the reader which strings mean missing; the guide to reading CSV files into R covers that step. A column that was read as character will not respond to is.na() for those entries, which is the usual reason a replacement “does nothing”.
Install or access (official source only)
Base R needs no extra package: is.na(), replace() and the assignment form are part of the language. replace_na() belongs to the tidyr package and coalesce() to dplyr, both from CRAN and documented at tidyr.tidyverse.org and dplyr.tidyverse.org. Install and load them with install.packages("tidyr") and library(tidyr) (and likewise for dplyr).
Step-by-step task
Replace NA with 0 in one vector
- Pick the function. Using the tidyr reference examples:
df$x |> replace_na(0). - Or use dplyr. The dplyr reference gives
x <- c(1, 2, NA, NA, 5, NA)followed bycoalesce(x, 0), which returns1 2 0 0 5 0. - In base R,
replace(x, is.na(x), 0)follows the documented signaturereplace(x, list, values), wherelistis an index vector (here the logical vector fromis.na()) andvaluesthe replacement.
Replace NA with 0 in one column of a data frame
- Use the tidyr reference form:
df |> dplyr::mutate(x = replace_na(x, 0)). - Check that the column is numeric first. tidyr casts each replacement value to the type of the column it replaces, so a numeric 0 fits a numeric column. For a character column, give a text replacement instead, as in the named-list example below.
Replace NA in several columns with different values
For a data frame, give replace_na() a named list with one value per column. The tidyr reference example is df |> replace_na(list(x = 0, y = "unknown")): column x gets 0 and column y gets the text “unknown”. Use this instead of one blanket fill when a data frame mixes numbers and text.
Replace NA with 0 across the whole data frame
Because is.na(df) returns a logical matrix with the data frame’s dimensions (see above), it can be used as an index: df[is.na(df)] <- 0 sets every flagged cell to 0. This is a general base R idiom built on the documented behaviour of is.na(); apply it only when every column should take 0. Do not write df[] <- 0, which overwrites every value, not only the missing ones.
Replace with a value from another column
coalesce(x, y) takes the first non-missing value at each position, so 0 can be the last fallback: coalesce(x, y, 0). Inputs are recycled and cast to a common type. For conditional logic beyond missing values, see the R if statement guide and the guide to ifelse in R.
Output and how to read it
The result has the same type as the input, per the tidyr reference. Check it two ways: sum(is.na(x)) should now be 0, and a count of zeros should have grown by the number of NAs you replaced. If the NA count did not change, the missing entries are probably text such as “NA” or “N/A” in a character column rather than true NA.
Troubleshooting
Nothing changed after replacing
The column is likely character. The string “NA” is not missing according to the R documentation, so is.na() returns FALSE for it. Re-read the file with the missing-value strings declared, or convert deliberately.
The replacement has the wrong type
Because the replacement is cast to the column type, match it to the column: 0 for numeric columns, text for character columns.
NaN values
is.na() is TRUE for NaN in numeric data, so base R replacement catches NaN too. Keep that in mind if your analysis treats NaN differently from NA.
You want the reverse
dplyr’s na_if() goes the other way and turns a chosen value into NA. For the Python equivalent of missing values, see the NumPy NaN guide.
Free alternatives (table)
All of these are free and open source; they differ in package and scope.
| Approach | Package | Scope, from the documentation |
|---|---|---|
df[is.na(df)] <- 0 |
base R | Whole data frame, using the logical matrix from is.na() |
replace(x, is.na(x), 0) |
base R | One vector; values are recycled if necessary |
replace_na(x, 0) |
tidyr | Vector or data frame; a named list gives one value per column |
coalesce(x, 0) |
dplyr | First non-missing value per position; inputs cast to a common type |
FAQ
How do I replace NA with 0 in R?
Use replace_na(x, 0) from tidyr or coalesce(x, 0) from dplyr for a vector or column, or df[is.na(df)] <- 0 for a whole data frame in base R.
Should I replace NA with 0?
Only if a missing entry genuinely means zero. Otherwise 0 is an invented measurement; keep the NA or use a deliberate missing-data approach, as outlined in the data cleaning steps guide.
Why does replace_na not change my “NA” text?
The string “NA” is not a missing value in R. Only true NA is detected by is.na().
Sources (official docs)
- tidyr reference, replace_na(): https://tidyr.tidyverse.org/reference/replace_na.html (checked 2026-10-29)
- dplyr reference, coalesce(): https://dplyr.tidyverse.org/reference/coalesce.html (checked 2026-10-29)
- R documentation, NA: https://stat.ethz.ch/R-manual/R-devel/library/base/html/NA.html (checked 2026-10-29)
- R documentation, replace: https://stat.ethz.ch/R-manual/R-devel/library/base/html/replace.html (checked 2026-10-29)







