OMOP Common Data Model — cohort analytics
person · visit_occurrence · condition_occurrence · measurement · concept vocabulary · ATLAS
# Python ≥3.13!
uv python install 3.13
uv venv --python 3.13
uv add pysynthea duckdb
from pysynthea.setup.setup import *
setup_db(database="small") # or full (Zenodo)
conn = connect_db("small")
OMOP example DB generated by Synthea™ — realistic longitudinal records
→ PyPI: pysynthea# omop_mini.db = person +
# condition_occurrence
import duckdb
conn = duckdb.connect("omop_mini.db")
schema ย่อ แต่ฝึก JOIN/GROUP BY ได้เหมือนกัน — notebook รองรับทั้ง 2 path อัตโนมัติ
→ week11 §4 (สร้าง db)| Table | หน้าที่ |
|---|---|
| concept | catalog ทุก code: concept_id ↔ name/vocabulary |
| concept_ancestor | hierarchy — E11 ลูกหลานทุกระดับ |
| concept_synonym | ค้นด้วยชื่อภาษาอื่น |
-- หา T2DM concepts
SELECT concept_id, concept_name
FROM concept
WHERE LOWER(concept_name)
LIKE '%type 2 diabetes%';
-- Full CDM:
SELECT DISTINCT co.person_id
FROM condition_occurrence co
JOIN concept c
ON c.concept_id =
co.condition_concept_id
WHERE c.concept_id IN (201820) -- E11
OR c.concept_ancestor... -- via ancestor
-- Mini-CDM (wk11):
SELECT person_id
FROM condition_occurrence
WHERE condition_concept_name
LIKE '%Diabetes%';
-- index date per patient:
SELECT person_id,
MIN(condition_start_date) idx_dt
FROM condition_occurrence
WHERE condition_concept_id IN (201820)
GROUP BY person_id;
SELECT
CASE WHEN gender_concept_id=8507 THEN 'M'
WHEN gender_concept_id=8532 THEN 'F' END g,
COUNT(DISTINCT p.person_id) n_all,
COUNT(DISTINCT co.person_id) n_dm,
ROUND(100.0*COUNT(DISTINCT co.person_id)
/COUNT(DISTINCT p.person_id),1) pct_dm
FROM person p
LEFT JOIN condition_occurrence co
ON co.person_id=p.person_id
AND co.condition_concept_id IN (201820)
GROUP BY g ORDER BY g;
LEFT JOIN + COUNT(DISTINCT) = prevalence ไม่ double-count
| Characteristic | Overall (N=…) | SQL building block |
|---|---|---|
| Age, mean (sd) | 58.3 ± 16.2 | AVG/YEAR(CURDATE)-year_of_birth |
| Female, % | 54.1% | SUM(gender=8532)/COUNT(*) |
| T2DM, % | 31.7% | LEFT JOIN cond + pct |
| HTN, % | 42.0% | concept 320128 join |
ดร.วิชิต สมบัติ — wichit.s@ubu.ac.th