'Paste together results within case_when (if-else) statements

I want to paste together results within the same case_when statement (i.e., if multiple statements are true for a given row). I know that I could do something like below to create additional columns and then unite them together. But what is the best way to make the code more efficient (and less verbose) without having to explicitly create var.m and var.o?

Data

df <- structure(list(
  ind = 1:10,
  var = c(-21, -60, 7, 8,
           9, 10, NA, 14, 101, 160)
),
class = "data.frame",
row.names = c(NA, -10L))

Code

library(tidyverse)

df %>%
  mutate(
    var.m = ifelse(row.names(df) %in% (which(abs(diff(var, lag = 1)) > 10)), "derivative", NA),
    var.o = ifelse((var + 50) > 90, "add", NA),
    results = case_when(is.na(var) ~ "Missing Data",
                     var > 100 ~ "High",
                     var < -20 ~ "Low")) %>%
  unite(
    "message",
    c(var.m, results, var.o),
    sep = "_",
    remove = TRUE,
    na.rm = TRUE
  )

Output/Expected Output

   ind var             message
1    1 -21      derivative_Low
2    2 -60      derivative_Low
3    3   7                    
4    4   8                    
5    5   9                    
6    6  10                    
7    7  NA        Missing Data
8    8  14          derivative
9    9 101 derivative_High_add
10  10 160            High_add

So, in other words, is it possible to forgo creating var.m and var.o and do everything within case_when? Or is there an alternative to creating multiple variables (i.e., var.m and var.o) before concatenating the messages together?



Solution 1:[1]

df %>%
  mutate(
    message = paste(
      coalesce(if_else(c(abs(diff(var, lag = 1)) > 10, FALSE), "derivative", ""), ""),
      coalesce(if_else((var+50) > 90, "add", ""), ""),
      coalesce(case_when(
        is.na(var) ~ "Missing Data",
        var > 100 ~ "High",
        var < -20 ~ "Low"), ""),
      sep = "_"),
    message = gsub("^_|_$", "",
                   gsub("__", "_", message))
  )
#    ind var             message
# 1    1 -21      derivative_Low
# 2    2 -60      derivative_Low
# 3    3   7                    
# 4    4   8                    
# 5    5   9                    
# 6    6  10                    
# 7    7  NA        Missing Data
# 8    8  14          derivative
# 9    9 101 derivative_add_High
# 10  10 160            add_High

The coalesce calls are because any one of them could be NA because of the possibility of things slipping through. I could add !is.na(var) before some of the conditionals, but diff introduces a challenge since we'd also need !lead(is.na(var),default=F) or such; and for that coalesce just seemed simpler.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1