20

I would like to replace NAs in numeric columns using some variation of mutate_if and replace_na if possible, but can't figure out the syntax.

df <-tibble(
    first = c("a", NA, "b"),
    second = c(NA, 2, NA),
    third = c(10, NA, NA)
  )

#> # A tibble: 3 x 3
#>   first second third
#>   <chr>  <dbl> <dbl>
#> 1 a      NA     10.0
#> 2 <NA>    2.00  NA  
#> 3 b      NA     NA

Final result should be:

#> # A tibble: 3 x 3
#>   first second third
#>   <chr>  <dbl> <dbl>
#> 1 a       0     10.0
#> 2 <NA>    2.00   0  
#> 3 b       0      0

My attempts look like:

df %>% mutate_if(is.numeric , replace_na(., 0) )
#>Error: is_list(replace) is not TRUE
Nettle
  • 3,193
  • 2
  • 22
  • 26

2 Answers2

38
df %>% mutate_if(is.numeric , replace_na, replace = 0)

# A tibble: 3 x 3
#  first second third
#  <chr>  <dbl> <dbl>
#1 a       0     10.0
#2 NA      2.00   0  
#3 b       0      0  
Dan
  • 11,370
  • 4
  • 43
  • 68
  • 1
    Excellent! I searched for an elegant solution for this, which I though, quite common problem and only found even more confusing answers. This is THE solution! Thanx – Bernd V. Nov 22 '18 at 16:17
  • Error in is_fun_list(.funs) : object 'replace_na' not found – stallingOne Nov 28 '21 at 07:22
  • The `mutate_if` function in `dplyr` has been suspended and replaced by `across`. I have added a solution in a separate answer. – Jochem Jul 21 '22 at 11:26
7

The in another answer mentioned solution based on mutate_if is based on a suspended function in dplyr. The suggested alternative is to use the across() function. Here a solution using that one:

df %>% 
  mutate(
    across(where(is.numeric), ~replace_na(.x, 0))
  )

# A tibble: 3 × 3
  first second third
  <chr>  <dbl> <dbl>
1 a          0    10
2 NA         2     0
3 b          0     0
Jochem
  • 3,295
  • 4
  • 30
  • 55