R (tidyverse)+
library(dplyr)
# Sample data
dm <- tibble(
USUBJID = c("101-001", "101-002", "101-003", "101-004"),
AGE = c(35, 64, NA, 17)
)
# .default used when no condition matches
dm1 <- dm %>%
mutate(agegrp = case_when(
AGE < 18 ~ "< 18 Years",
AGE >= 60 ~ ">= 60 Years",
.default = "18-59 Years"
))
# Missing values handled separately
dm2 <- dm %>%
mutate(agegrp = case_when(
is.na(AGE) ~ "Age Missing",
AGE < 18 ~ "< 18 Years",
AGE >= 60 ~ ">= 60 Years",
.default = "18-59 Years"
))- For multi-branch logic in tidyverse, we reach for
case_when()from dplyr. - Each line inside
case_when()is acondition ~ valuepair; dplyr evaluates them top-to-bottom and returns the value for the first matching condition. - In the first example, a row with
AGE = NAdoes not matchAGE < 18orAGE >= 60(NA comparisons return NA, not TRUE). So it falls through to.defaultand gets "18-59 Years" — probably not what we want. - In the second example, we add an explicit
is.na(AGE) ~ "Age Missing"branch as the first line. Because case_when stops at the first match, missing ages get their own label and never reach the numeric comparisons. .default =replaces the olderTRUE ~ valuetrick. Both still work;.defaultis clearer.- After running, we check that the missing row has the right label in each output.