My data takes this format:
library(tidyverse)
df <- mtcars
df <- df %>% mutate(vs_doubled = vs * 2) %>% select(mpg, cyl, vs, am, vs_doubled)
head(df)
#> mpg cyl vs am vs_doubled
#> 1 21.0 6 0 1 0
#> 2 21.0 6 0 1 0
#> 3 22.8 4 1 1 2
#> 4 21.4 6 1 0 2
#> 5 18.7 8 0 0 0
#> 6 18.1 6 1 0 2
I'm trying to use mutate_at
and na_if
to set 0 values as NA--but only for specific columns ("vs" and "am"). I would like to leave the column "vs_doubled" with zeros in it.
I haven't quite got it right, because the following line doesn't work:
df <- df %>% mutate_at(.vars = c("vs", "am"), .funs = na_if(y = 0))
Update
From dplyr
1.0.0 we can use across
:
library(dplyr)
df %>% mutate(across(c(vs,am), na_if, 0)) %>% head
# mpg cyl vs am vs_doubled
#1 21.0 6 NA 1 0
#2 21.0 6 NA 1 0
#3 22.8 4 1 1 2
#4 21.4 6 1 NA 2
#5 18.7 8 NA NA 0
#6 18.1 6 1 NA 2
Original answer
In the previous versions of dplyr
we can use mutate_at
:
df %>% mutate_at(vars(vs,am), ~na_if(.,0)) %>% head
Or another way would be
df %>% mutate_at(vars(vs,am), na_if, 0)
~
is purrr-styled formula syntax whereas .
represents value of the column. It's an alternative to anonymous function calls with which you would have written the above function as
df %>% mutate_at(vars(vs,am), function(x) na_if(x, 0))
Also the alternative way shown does not require ~
and we can directly pass the function with additional arguments (which is 0 here for y
).
And of course there are other ways to do this without using na_if
df %>% mutate_at(vars(vs, am), ~replace(., . == 0, NA))
Or the same with base R
cols <- c("vs", "am")
df[cols] <- lapply(df[cols], function(x) replace(x, x == 0, NA))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With