Home > Mobile >  How to paste together results within case_when (if-else) statements?
How to paste together results within case_when (if-else) statements?

Time:01-19

I'm wondering if it is possible 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 together. But I'm wondering if there is a more efficient way to do this (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?

CodePudding user response:

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.

  •  Tags:  
  • Related