Portfolio Project · Clinical Data Analysis

Adverse Events Analysis
CARDIO-2024 Study

A Python-based analysis of adverse event data from a simulated Phase II cardiovascular clinical trial, structured according to CDISC SDTM standards. This project demonstrates the application of CRA domain knowledge to automate data quality checks, classify AE severity, and flag patients requiring clinical review.

Python Pandas Matplotlib CDISC SDTM AE Classification Data QC ICH-GCP
23
Total Adverse Events Analyzed
10
Study Participants
5
Serious AEs Flagged

AE Severity Distribution

CARDIO-2024 · Adverse Events by Severity Grade · N=23
MILD
12
MODERATE
6
SEVERE
5

Generated with Python (Matplotlib) · Data structured per CDISC SDTM AESEV variable

Key Findings

⚠️ Serious Adverse Events (SAEs)
  • PT-002 — Chest Pain (SEVERE)
  • PT-004 — Hypertension (SEVERE)
  • PT-007 — Chest Pain (SEVERE)
  • PT-008 — Fatigue (SEVERE)
  • PT-010 — Hypertension (SEVERE)
🔍 Patients Flagged for Review
  • PT-002 — 3 AEs · Review needed
  • PT-004 — 4 AEs · Highest priority
  • PT-007 — 3 AEs · Review needed
  • PT-010 — 3 AEs · Review needed
📊 Severity Breakdown
  • MILD: 12 events (52%)
  • MODERATE: 6 events (26%)
  • SEVERE: 5 events (22%)
  • SAE Rate: 21.7% of all AEs
🏥 Most Common AE Terms
  • Headache — 4 occurrences
  • Fatigue — 4 occurrences
  • Dizziness — 3 occurrences
  • Hypertension — 3 occurrences

Python Analysis Script

# AE Analysis — CARDIO-2024 Clinical Trial
# Author: Judith Lavric | CRA & Clinical Data Specialist
# Tools: Python · Pandas · Matplotlib · CDISC SDTM

import pandas as pd
import matplotlib.pyplot as plt

# Load CDISC SDTM-structured dataset
df = pd.read_csv("ae_dataset.csv")

print("=== CARDIO-2024 STUDY - AE REPORT ===")
print("Total AEs:", len(df))

# AE severity distribution
print("=== AEs BY SEVERITY ===")
print(df["AESEV"].value_counts())

# Flag serious adverse events (AESER == "Y")
serious = df[df["AESER"] == "Y"]
print(serious[["USUBJID", "AETERM", "AESEV"]])

# Identify patients with >2 AEs — flag for clinical review
ae_count = df.groupby("USUBJID").size()
for patient, count in ae_count.items():
    if count > 2:
        print("ACHTUNG:", patient, "hat", count, "AEs - Review needed!")

# Generate severity distribution chart
severity = df["AESEV"].value_counts()
plt.figure(figsize=(8,5))
plt.bar(severity.index, severity.values,
        color=["#94d2bd", "#0a9396", "#0d1b2a"])
plt.title("AE Severity Distribution - CARDIO-2024")
plt.savefig("ae_chart.png")

Skills Demonstrated

🐍
Python & Pandas
Loaded and analyzed a structured clinical dataset using Pandas DataFrames — filtering, grouping, and counting adverse events automatically.
📋
CDISC SDTM Standards
Structured the dataset using real CDISC SDTM variable names (USUBJID, AETERM, AESEV, AESER, AEREL) — the industry standard for clinical trial data.
🔍
Clinical Data QC
Applied CRA monitoring logic to automatically flag patients with >2 AEs and identify serious adverse events — replacing manual review.
📊
Data Visualization
Generated a publication-quality severity distribution chart using Matplotlib — translating raw data into clear clinical insights.
🏥
Domain Knowledge
Combined 3+ years of hands-on CRA experience with Python to build a tool that reflects real clinical monitoring workflows.
Automation
Replaced manual Excel-based AE review with an automated Python script — demonstrating the efficiency gains possible with clinical data programming.