This workflow uses six entirely fabricated dictionary rows. The identifiers and observation counts are teaching examples, not genuine clinical codes or data. Users obtain a real dictionary separately through their CPRD access arrangements. Search output is a set of candidates to review against a study definition.
library(cprd.search)
file <- system.file("extdata", "synthetic-dictionary.tsv", package = "cprd.search")
dictionary <- load_cprd_dictionary(file)
#> Loaded 6 medical terms.
names(dictionary)
#> [1] "MedCodeId" "Observations" "OriginalReadCode"
#> [4] "CleansedReadCode" "Term" "SnomedCTConceptId"
#> [7] "SnomedCTDescriptionId" "Release" "EmisCodeCategoryId"
#> [10] "term_lower"MedCodeId, Term and
Observations are required. Codes are read as character,
while counts are numeric. A different explicit path switches
dictionaries; force = TRUE refreshes the same path after a
file changes.
cprd_search("family history", "lung cancer")
#> Found 1 matching terms.
#> # A tibble: 1 × 9
#> MedCodeId Observations OriginalReadCode CleansedReadCode Term
#> <chr> <dbl> <chr> <chr> <chr>
#> 1 00004 30 B0001 B0001 family history of lu…
#> # ℹ 4 more variables: SnomedCTConceptId <chr>, SnomedCTDescriptionId <chr>,
#> # Release <chr>, EmisCodeCategoryId <chr>
cprd_search_or("diabetes", "asthma", min_obs = 20)
#> Found 3 matching terms.
#> # A tibble: 3 × 9
#> MedCodeId Observations OriginalReadCode CleansedReadCode Term
#> <chr> <dbl> <chr> <chr> <chr>
#> 1 00001 100 C10.. C10.. diabetes
#> 2 00002 50 C10.1 C10.1 gestational diabetes
#> 3 00005 20 H33.. H33.. asthma
#> # ℹ 4 more variables: SnomedCTConceptId <chr>, SnomedCTDescriptionId <chr>,
#> # Release <chr>, EmisCodeCategoryId <chr>
review <- cprd_search_exclude("diabetes", exclude = "gestational")
#> Found 1 matching terms.
review[, c("MedCodeId", "Term")]
#> # A tibble: 1 × 2
#> MedCodeId Term
#> <chr> <chr>
#> 1 00001 diabetesKeywords are case-insensitive literal substrings. The default does
not interpret code punctuation as a regular expression. Use
regex = TRUE deliberately when patterns are needed:
cprd_search("H33..", column = "CleansedReadCode")
#> Found 1 matching terms.
#> # A tibble: 1 × 9
#> MedCodeId Observations OriginalReadCode CleansedReadCode Term
#> <chr> <dbl> <chr> <chr> <chr>
#> 1 00005 20 H33.. H33.. asthma
#> # ℹ 4 more variables: SnomedCTConceptId <chr>, SnomedCTDescriptionId <chr>,
#> # Release <chr>, EmisCodeCategoryId <chr>
cprd_search("^asthma$", regex = TRUE)
#> Found 1 matching terms.
#> # A tibble: 1 × 9
#> MedCodeId Observations OriginalReadCode CleansedReadCode Term
#> <chr> <dbl> <chr> <chr> <chr>
#> 1 00005 20 H33.. H33.. asthma
#> # ℹ 4 more variables: SnomedCTConceptId <chr>, SnomedCTDescriptionId <chr>,
#> # Release <chr>, EmisCodeCategoryId <chr>cprd_search_fuzzy("diabeties", select = c("MedCodeId", "Term", "dist"))
#> Found 1 fuzzy matches.
#> # A tibble: 1 × 3
#> MedCodeId Term dist
#> <chr> <chr> <dbl>
#> 1 00001 diabetes 1
cprd_search_fuzzy("xiabetes", max_dist = 1)
#> Found 1 fuzzy matches.
#> # A tibble: 1 × 10
#> MedCodeId Observations OriginalReadCode CleansedReadCode Term
#> <chr> <dbl> <chr> <chr> <chr>
#> 1 00001 100 C10.. C10.. diabetes
#> # ℹ 5 more variables: SnomedCTConceptId <chr>, SnomedCTDescriptionId <chr>,
#> # Release <chr>, EmisCodeCategoryId <chr>, dist <dbl>The default optimal-string-alignment distance counts edits to the
whole term, with a maximum of two. It does not search each word inside
longer phrases. jw, cosine and
jaccard use normalized distances and default to 0.1; their
thresholds must be within 0–1. Review approximate matches before
including them in a code list.
asthma <- cprd_search("asthma", select = c("MedCodeId", "Term"))
#> Found 1 matching terms.
diabetes <- cprd_search("diabetes", select = c("MedCodeId", "Term"))
#> Found 2 matching terms.
codes <- cprd_combine(asthma, diabetes, diabetes)
#> Combined: 3 unique terms.
codes
#> # A tibble: 3 × 2
#> MedCodeId Term
#> <chr> <chr>
#> 1 00005 asthma
#> 2 00001 diabetes
#> 3 00002 gestational diabetesCombining keeps the first occurrence of each medical code. It sorts by observation count when available and otherwise retains input order.
Exporting requires an explicit output path; there is no default filename or directory. An existing file at that path is overwritten. Here we use a temporary file and remove it after reading it back.
output <- tempfile(fileext = ".csv")
cprd_export(codes, output)
#> Exported 3 rows to: /tmp/RtmpBPGW8P/file1cbbe24f2ef.csv
restored <- utils::read.csv(output, colClasses = "character")
stopifnot(identical(restored$MedCodeId, codes$MedCodeId))
restored
#> MedCodeId Term
#> 1 00005 asthma
#> 2 00001 diabetes
#> 3 00002 gestational diabetes
unlink(output)Always tell the importing software that identifier columns contain text. Automatic numeric conversion can remove leading zeroes or round long IDs. The package’s synthetic tests exercise export/reimport, search behavior, empty results and invalid input without requiring access to real CPRD files.