Below is one approach to mapping cpt_code into one of the defined titles using the case_when() and between() functions. Warnings are generated due to the Dental and DME codes becoming NA when converted to numeric (because the code starts with a letter) within the between() function, but these cases are specifically handled within the case_when() statement.
library(tidyverse)
# sample data
df = data.frame(
id = 1:8,
cpt_code = c('99201', '00107', '12021', '70011',
'85001', '99606', 'D0122', 'E0100')
)
df_coded = df %>%
mutate(title = case_when(
substr(cpt_code,1,1) == 'D' ~ 'Dental',
substr(cpt_code,1,1) == 'E' ~ 'DME',
between(as.numeric(cpt_code), 99201, 99499) ~ 'Evaluation and Management',
between(as.numeric(cpt_code), 100, 1999) |
between(as.numeric(cpt_code), 99100, 99140) ~ 'Anesthesia',
between(as.numeric(cpt_code), 10021, 69990) ~ 'Surgery',
between(as.numeric(cpt_code), 70010, 79999) ~ 'Radiology',
between(as.numeric(cpt_code), 80047, 89398) ~ 'Pathology and Laboratory',
between(as.numeric(cpt_code), 90281, 99199) |
between(as.numeric(cpt_code), 99500, 99607) ~ 'Medicine',
TRUE ~ 'ERROR' # catch-all in case a cpt_code is not mapped
))
df_coded
#> id cpt_code title
#> 1 1 99201 Evaluation and Management
#> 2 2 00107 Anesthesia
#> 3 3 12021 Surgery
#> 4 4 70011 Radiology
#> 5 5 85001 Pathology and Laboratory
#> 6 6 99606 Medicine
#> 7 7 D0122 Dental
#> 8 8 E0100 DME
Created on 2023-04-15 with reprex v2.0.2