mutate two or more columns if case_when is used

I am trying to use the case_when function for a bunch of columns y a data.frame.

This case does not return the specified columns in mutate

cars %>% mutate (
km = speed * dist,
mt = km / 1000
) %>%
mutate (
.funs = case_when(
(speed < 20 ) ~ {
km = km * 2
mt = mt * 3
}
)
)

Thanks

We could use mutate_at

library(tidyverse)
cars %>%
mutate(km = speed * dist, mt = km/1000) %>%
mutate_at(vars(km, mt), funs(case_when(speed < 20 ~ .*2,
TRUE ~ .)))

If we need to do computation with separate values for each of the column, then use map2 or pmap

out <- cars %>%
mutate(km = speed * dist, mt = km/1000)  %>%
select(km, mt) %>%
map2_df(., list(2, 3), ~
case_when(cars\$speed < 20 ~ .x * .y, TRUE ~ .x)) %>%
bind_cols(cars, .)

#  speed dist  km    mt
#1     4    2  16 0.024
#2     4   10  80 0.120
#3     7    4  56 0.084
#4     7   22 308 0.462
#5     8   16 256 0.384
#6     9   10 180 0.270

Discover this solution, but is a bit weird and tricky

mutate_when <- function (data, ...) {
dots <- eval (substitute (alist(...)))
for (i in seq (1, length (dots), by = 3)) {
condition <- eval (dots [[i]], envir = data)
mutations <- eval (dots [[i + 1]], envir = data [condition, ])
data[condition, names(mutations)] <- mutations
mutations_else <- eval (dots [[i + 2]], envir = data [!condition, ])
data[!condition, names(mutations)] <- mutations_else
}
data
}

cars %>%
mutate(
km = speed * dist,
mt = km/1000
) %>%
mutate_when(
speed < 20,
list (
km = km * 2,
mt = mt * 3
),
list (
0
)
)

Gives

speed dist   km    mt
1      4    2   16 0.024
2      4   10   80 0.120
3      7    4   56 0.084
4      7   22  308 0.462
5      8   16  256 0.384
6      9   10  180 0.270
The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

# More Articles