Search code examples
rcase

How to mutate based on condition using case_when using R


I’m struggling to find a way to create a new variable based on conditions. In this case I want to create a variable called “size” based on the variable called “number”, but the rules for “size” is different depending on the variable called “type”. So when "number" is 1 then one set of case_when rules should apply, when "number" is 2 another set of case_whn rules should apply.

# Load libraries
library(tidyverse)

# Create data
dat <- tribble(
  ~number, ~type,
   232,      1,
   383,      2,
   832,      1,
   722,      2,
   134,      1,
   211,      2,
   970,      1
)

# This works

dat |> mutate(size = case_when(
  number > 400 ~ "big",
  number < 400 ~ "medium",
  number < 200 ~ "small"
))

# This also works

dat |> mutate(size = case_when(
  number > 700 ~ "super big",
  between(number, 400, 700) ~ "quite medium",
  number < 400 ~ "quite small"
))

# I would like do this, but it doesn't work
dat %>% 
  if (type == 1) {
    mutate(size = case_when(
      number > 400 ~ "big",
      number < 400 ~ "medium",
      number < 200 ~ "small"
    ))
  } else {
    mutate(size = case_when(
      number > 700 ~ "super big",
      between(number, 400, 700) ~ "quite medium",
      number < 400 ~ "quite small"
    ))
  }

The expected result should be like this:

number  type size
232     1    medium
383     2    quite small
832     1    big
722     2    super big
134     1    medium
211     2    quite small
970     1    big

Solution

  • You could directly use case_match:

    dat %>%
      mutate(size = case_match(type,
        1 ~ case_when(
                        number > 400 ~ "big",
                        number < 400 ~ "medium",
                        number < 200 ~ "small"),
        2 ~ case_when(
                        number > 700 ~ "super big",
                        between(number, 400, 700) ~ "quite medium",
                        number < 400 ~ "quite small")))
    
    # A tibble: 7 × 3
      number  type size       
       <dbl> <dbl> <chr>      
    1    232     1 medium     
    2    383     2 quite small
    3    832     1 big        
    4    722     2 super big  
    5    134     1 medium     
    6    211     2 quite small
    7    970     1 big