Skip to contents

Background

PicnicHealth utilizes OMOP, or the Observational Medical Outcomes Partnership Common Data Model, as the basis of our data model. Clinical concepts in PicnicHealth datasets are mapped to a concept in the OMOP data model.

The OMOP data model can make analyzing the dataset easier by helping you discover hierachical relationships between concepts rather than developing exhaustive code lists. The concept tables in your PicnicHealth dataset - concept, concept_ancestor, and concept_relationship, and drug_to_ingredient_map - provide the ontological information you need to build code lists.

Below, we show two examples - one for medications, and one for procedures.

Note that special considerations for building code lists apply in the conditions domain depending on the date that your dataset was created; see the vignette “ICD and SNOMED codes for clinical conditions” for more details.

Identifying medications from an active ingredient

In OMOP and the PicnicHealth dataset, medications are coded in the RxNorm ontology.

The drug_to_ingredient_map table provides a convenient mapping of drug names to their primary active ingredient. This is derived from the concept_ancestor table. This enables you to easily find all brand names and dose forms with a shared active ingredient that may appear in medical records.

[1] Use a tool such as OHDSI’s Athena or RxNav to find an ingredient of interest. In this example, we’ll look for drugs with the active ingredient acetaminophen (RxNorm 161).

[2] Load up the PicnicHealth package, and the data provided.

library(PicnicHealth)
library(dplyr)

data_set = load_data_set(data_path)
list2env(data_set, envir = .GlobalEnv)

[3] Filter the concept table to rows where domain_concept_code = 161 and the vocabulary = RxNorm.

aceta_concept = concept %>%
  filter(domain_concept_code == "161" &
           vocabulary == "RxNorm (NLM)")

[4] Inner join this filtered table to the drug_to_ingredient_map table (fields to join: concept_id ←→ ingredient_concept_id).

aceta_descendants = aceta_concept %>%
  inner_join(drug_to_ingredient_map,
             by = c("concept_id" = "ingredient_concept_id"))

[4] Join this filtered table to visit_medication_list_occurrence on the field drug_concept_id to find all relevant treatments.

aceta_meds_list = aceta_descendants %>%
  inner_join(visit_medication_list_occurrence, 
             by = c("drug_concept_id", "drug_concept_name")) %>%
  select(visit_medication_list_occurrence_id, 
         ingredient_concept_name, drug_concept_name, 
         visit_id)
visit_medication_list_occurrence_id ingredient_concept_name drug_concept_name visit_id
1f789e24-355d-4be2-8862-5adfe96a7d92 Acetaminophen Vicodin b467be29-0ad4-41e7-9d25-52abee680e4d
d53e5d7e-ad39-4b47-a2a7-d484465e7865 Acetaminophen Tylenol 3113ba0b-deb2-4230-a04c-05e3bfbfb373
c33d0f47-480f-4725-b1f2-6cd83ab728a7 Acetaminophen Mapap ce45804a-d12f-4306-8157-533c9ec70691
61765483-35af-44aa-8a49-02c268bc15de Acetaminophen Excedrin 7e0fcfe6-0da4-4223-bbc4-95d9f963d5a9
ee3b299a-a061-4312-926c-d5371d45a6ca Acetaminophen Percocet 73379f61-a742-4356-9eee-8f2c88f3f434
bfb854d7-683a-4e63-aece-45c91f2100dd Acetaminophen Tylenol with Codeine bb28327a-a1a8-4e36-9deb-f57b2d0d776e

Identifying procedures with a common ancestor

Note that procedures are rarely coded in procedure reports, and when they are it is to CPT codes, which we do not capture. PicnicHealth abstractors instead map procedures to SNOMED codes, which you will find in the procedure_occurrence and (if applicable to your dataset) cohort_procedure_occurrence tables.

[1] Use OHDSI’s Athena search tool to inspect the OMOP code lists for your concept of interest. In this example, we’ll look for instances of MRI of head, SNOMED code 241601008, and all concepts falling under it.

[2] Load up the PicnicHealth package, and the data provided.

library(PicnicHealth)
library(dplyr)

data_set = load_data_set(data_path)
list2env(data_set, envir = .GlobalEnv)

[3] Filter the concept table to rows where domain_concept_code = 241601008

mri_of_head_concept = concept %>%
  filter(domain_concept_code == "241601008" &
           vocabulary == "Systematic Nomenclature of Medicine - Clinical Terms (IHTSDO)")

[4] Inner join this filtered table to the concept_ancestor table (fields to join: concept_id ←→ ancestor_concept_id).

mri_of_head_descendants = mri_of_head_concept %>%
  inner_join(concept_ancestor,
             by = c("concept_id" = "ancestor_concept_id"))

[4] Join this filtered table to procedure (fields to join: descendant_concept_id ←→ procedure_concept_id) to find all instances where a descendant concept of “MRI of head” was present in a patient’s medical record.

mri_of_head_procedures = mri_of_head_descendants %>%
  inner_join(procedure_occurrence, 
             by = c("descendant_concept_id" = "procedure_concept_id")) %>%
  select(procedure_occurrence_id, procedure_concept_name, visit_id)
procedure_occurrence_id procedure_concept_name visit_id
7da88dce-dffa-4838-84b1-a491d97f9ac5 MRI of brain with contrast be5d1373-de77-4b4c-ba18-e7946114919e
a9f5287e-b0f2-494f-b4f5-95812ca193d4 MRI of orbit with contrast 567e303b-9106-436f-bace-4b30a0b59ded
96162997-dcca-434c-abb5-5db15493a677 MRI of sella turcica without contrast 6301b76a-1b10-4134-9de1-c6970a899539
0e23c2f8-7f02-4fa9-80aa-e99aa0084dc7 MRI of brain without contrast 7e7698ed-fe8f-409e-b9f0-11ccb994d158