Search code examples
rdplyrlapplycase-when

clean code inside of mutate = case_when in dplyr


im wondering if it is possible to shorten up the code in this case_when() statement. Another important goal is to make the length inside the case_when() statement (amount of times lag(..., n=xy) below each other) variable. The purpose of this function is to find the closest leading object with the same id and assign a value to it. (but its more about not writing 10 times n=1,2,3,4,5...)

Here is my code:

  find.after <- function(data, expr) {
    data %>% mutate(
      "a.{{expr}}" := case_when(
        lead(id,1) == id ~ lead({{ expr }},1),
        lead(id,2) == id ~ lead({{ expr }},2),
        lead(id,3) == id ~ lead({{ expr }},3),
        lead(id,4) == id ~ lead({{ expr }},4),
        lead(id,5) == id ~ lead({{ expr }},5),
        lead(id,6) == id ~ lead({{ expr }},6),
        lead(id,7) == id ~ lead({{ expr }},7),
        lead(id,8) == id ~ lead({{ expr }},8),
        lead(id,9) == id ~ lead({{ expr }},9)
      )
    )
  }

tibble(id = rep(1:5,2), b = rep(c("a","b"),5)) %>%
  find.after(data = ., expr = b)

Any tipps would be super cool! Thank you in advance :)


Solution

  • You don't need the case_when here, you just need a group_by

    find.after <- function(data, expr) {
      data %>% 
        group_by(id) %>% 
        mutate("a.{{expr}}" = lead({{expr}}))
    }
    

    This way you are always only looking within the same id for the next value