0

I have this dataframe

dtf <- data.frame(
    id = seq(1, 4),
    amt = c(1, 4, NA, 123),
    xamt = c(1, 4, NA, 123),
    camt = c(1, 4, NA, 123),
    date = c("2020-01-01", NA, "2020-01-01", NA),
    pamt = c(1, 4, NA, 123)
)

I'd like to replace all NA values in case that colname is numeric, in my case amt, xamt, pamt and camt. I'm looking for dplyr way. Normally I would use

replace(is.na(.), 0)

But this not works because of date column.

Darren Tsai
  • 32,117
  • 5
  • 21
  • 51
  • 2
    In case one wants to use baseR: `rapply(dtf, classes = "numeric", f = function(x) replace(x, is.na(x), 0), how = "replace")` – markus Jul 29 '20 at 14:27

1 Answers1

5

You can use across :

library(dplyr)
dtf %>% mutate(across(where(is.numeric), ~replace(., is.na(.), 0)))
#mutate_if for dplyr < 1.0.0
#dtf %>% mutate_if(is.numeric, ~replace(., is.na(.), 0))

You can also use replace_na from tidyr :

dtf %>% mutate(across(where(is.numeric), tidyr::replace_na, 0))

#  id amt xamt camt       date pamt
#1  1   1    1    1 2020-01-01    1
#2  2   4    4    4       <NA>    4
#3  3   0    0    0 2020-01-01    0
#4  4 123  123  123       <NA>  123

As suggested by @Darren Tsai we can also use coalesce.

dtf %>% mutate(across(where(is.numeric), coalesce, 0))
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213