Reputation: 411
I have an example df:
df <- data.frame(
col1 = c(4,5,6,11),
col2 = c('b','b','c', 'b')
)
> df
col1 col2
1 4 b
2 5 b
3 6 c
4 11 b
and I mutate based on these conditions:
df2 <- df %>%
mutate(col3 = case_when(
col2 == 'b' & col1 == 4 ~ 10,
col2 == 'b' & col1 == 5 ~ 15,
col2 == 'b' & col1 == 11 ~ 20,
col2 == 'c' & col1 == 6 ~ 7)
)
> df2
col1 col2 col3
1 4 b 10
2 5 b 15
3 6 c 7
4 11 b 20
You can see that the first 3 conditions are repetitive in that they require col2 == 'b'. Is there some syntax or another package or more efficient way of combining same/similar conditions so that I don't need to repeat col2 == 'b'? Like a one liner that if col2 == 'b' then do these transformations.
Upvotes: 0
Views: 51
Reputation: 5722
You can write nested case_when
df %>% mutate(col3 = case_when(
col2=="b" ~ case_when(
col1 == 4 ~ 10,
col1 == 5 ~ 15,
col1 == 11 ~ 20),
col2=="c" ~ case_when(
col1 == 6 ~ 7)))
Another solution colud be using a auxiliary table, this way however will limit the flexibility of case_when and only works for equality matches but i suspect is a lot faster.
library(dplyr)
df <- data.frame(
col1 = c(4,5,6,11),
col2 = c('b','b','c', 'b')
)
choices <- data.frame(
col2 = c(rep("b",3),"c"),
col1 = c(4,5,11,6),
col3 = c(10,15,20,7)
)
df %>% left_join(choices, by = c("col1"="col1", "col2"="col2"))
#> col1 col2 col3
#> 1 4 b 10
#> 2 5 b 15
#> 3 6 c 7
#> 4 11 b 20
Be sure to capture the default unmatched cases.
Upvotes: 2