DeltaIV
DeltaIV

Reputation: 5646

Conditional mutating with dplyr for multiple columns at the same time

Conditional mutating in dplyr is "easy" (kind of) using if_else():

can dplyr package be used for conditional mutating?

However, suppose I want to mutate columns x,y,z at the same time, based on a logical condition C which depends on column group: also, the mutation happens only if C is TRUE, otherwise x,y,z stay the same. How can I do that? In base R, it's straightforward:

n <- 5 
k <- 10
my_labels <- LETTERS[1:5]

foobar <- data.frame(group = gl(n, k, labels = my_labels), x = runif(n*k), y=rnorm(n*k), z = rpois(n*k, 1), month_name = (rep(month.name[1:k], n)))

# mutate x, y, z, only if the condition on group is TRUE
foobar[foobar$group %in% c("B","E"), c("x", "y", "z")] <- NA

How do I achieve the same result with dplyr (if possible)?

Upvotes: 2

Views: 2056

Answers (2)

climatestudent
climatestudent

Reputation: 572

Using dplyr::across available from dplyr 1.0.0 onward, you could do:

foobar %>% 
  mutate(across(c(x, y, z), 
         ~ if_else(group %in% c("B", "E"), NA_real_, as.numeric(.x))))

Upvotes: 3

akrun
akrun

Reputation: 886938

We can use replace within mutate_at

library(dplyr)
foobar %>% 
   mutate_at(vars(x, y, z),
       funs(replace(., group %in% c("B", "E"), NA)))

If we want to use if_else

foobar %>% 
  mutate_at(vars(x, y, z),
      funs(if_else(group %in% c("B", "E"), NA_real_, as.numeric(.))))

Upvotes: 4

Related Questions