75

I'm trying to fill all NAs in my data with 0's. Does anyone know how to do that using replace_na from tidyr? From documentation, we can easily replace NA's in different columns with different values. But how to replace all of them with some value? I have many columns...

Using mtcars dataset as an example:

mtcars [sample(1:nrow(mtcars), 4), sample(1:ncol(mtcars), 4)]<- NA
mtcars %>% replace_na( ??? )
MultiplyByZer0
  • 6,302
  • 3
  • 32
  • 48
zesla
  • 11,155
  • 16
  • 82
  • 147

3 Answers3

151

If replace_na is not a mandatory requirement, following code will work:

mtcars %>% replace(is.na(.), 0)

Reference Issue: https://stackoverflow.com/a/45574804/8382207

Sagar
  • 2,778
  • 1
  • 8
  • 16
88

I found a way to get it working with replace_na as requested (as it is the fastest option via microbenchmark testing):

UPDATE with dplyr v1.0.0

This has been made much easier with addition of the dplyr::across function:

library(dplyr)
library(tidyr)

mtcars %>% 
  mutate(
    across(everything(), ~replace_na(.x, 0))
  )

# Or if you're pipe shy:
mutate(mtcars, across(everything(), ~replace_na(.x, 0)))

That's it! Pretty simple stuff.

For dplyr < v1.0.0

library(tidyr)
library(dplyr)

# First, create a list of all column names and set to 0
myList <- setNames(lapply(vector("list", ncol(mtcars)), function(x) x <- 0), names(mtcars))

# Now use that list in tidyr::replace_na 
mtcars %>% replace_na(myList)

To apply this to your working data frame, be sure to replace the 2 instances of mtcars with whatever you have named your working data frame when creating the myList object.

Dave Gruenewald
  • 5,329
  • 1
  • 23
  • 35
  • 2
    You can also use a dot to represent the data frame and use the list within a pipe. `mtcars %>% replace_na(setNames(lapply(vector("list", ncol(.)), function(x) x <- 0), names(.)))` – Todd Sep 09 '19 at 14:43
  • 2
    df %>% mutate( across(everything(), replace_na, 0) ) – Vincent Guyader Jun 10 '21 at 14:50
5
library(dplyr)
mydata <- mtcars
mydata[sample(1:nrow(mydata), 4), sample(1:ncol(mydata), 4)]<- NA
mydata %>% mutate_each(funs(replace(., is.na(.), 0)))
airstrike
  • 2,270
  • 1
  • 25
  • 26