Using replace_na with across in mutate

Viewed 3572

I am trying to replace NA in a subset of columns and I want to use tidyverse/dplyr syntax. dplyr v1.0.2

In the following, I want only to replace the NAs with 999 in columns ab,ac but not in ads

tbf <- tibble( ab = c(1,3,NA), ac = c(23,NA,33), d = c(22,22,NA), ads = c('ds', NA, "dwe"))
tbf %>% mutate(across(starts_with('a') & where(is.numeric)), ~replace_na(999))

does not seem to work.

I tried ~replace_na(.x,999) too. That didn't work either.

Any help is appreciated.

5 Answers

The fn (you are using replace_na) needs to be inside the across. You then also need to reference the current column by inserting a . in the replace_na. This way you can use the filtering you are proposing in your question (columns starting with "a" and with numeric values) as opposed to the other answers here which specifically use column names.

tbf %>% mutate(across(starts_with('a') & where(is.numeric), ~replace_na(.,999)))

Data

tbf <- tibble( ab = c(1,3,NA), ac = c(23,NA,33), d = c(22,22,NA), ads = c('ds', NA, "dwe"))

Code

library(dplyr)
library(tidyr)

tbf %>% 
  mutate(
    across(ab:ac, ~replace_na(.x, 999))
  )

Output

#> # A tibble: 3 x 4
#>      ab    ac     d ads  
#>   <dbl> <dbl> <dbl> <chr>
#> 1     1    23    22 ds   
#> 2     3   999    22 NA 
#> 3   999    33    NA dwe

Created on 2020-09-19 by the reprex package (v0.3.0)

Try this:

#Code
tbf %>% mutate(across(ab:ac, ~ifelse(is.na(.),999,.)))

Output:

# A tibble: 3 x 4
     ab    ac     d ads  
  <dbl> <dbl> <dbl> <chr>
1     1    23    22 ds   
2     3   999    22 NA   
3   999    33    NA dwe  

Please see if this works.

tbf %>% mutate(across(starts_with('a') & where(is.numeric), ~replace(., is.na(.), 999)))

> tbf %>% mutate(across(starts_with('a') & where(is.numeric), ~replace(., is.na(.), 999)))
# A tibble: 3 x 4
     ab    ac     d ads  
  <dbl> <dbl> <dbl> <chr>
1     1    23    22 ds   
2     3   999    22 NA   
3   999    33    NA dwe  
> 

You can do that with tidyr as well.

tbf %>% 
  mutate(across(starts_with('a') & where(is.numeric))) %>% 
  replace_na(list(ab = 999, ac = 999))

    # A tibble: 3 x 4
         ab    ac     d ads  
      <dbl> <dbl> <dbl> <chr>
    1     1    23    22 ds   
    2     3   999    22 NA   
    3   999    33    NA dwe 
Related