bolster.data_sources.health_ni.disease_prevalence
NISRA Disease Prevalence Module.
Provides access to Northern Ireland’s disease prevalence statistics from GP clinical disease registers (Quality & Outcomes Framework, QOF). Data are released annually after National Prevalence Day.
- Data Coverage:
Financial years 2017/18 to present (extended annually)
NI-level: registered patients per disease register and prevalence per 1,000 patients
By Local Government District (LGD): same metrics per council
By HSC Trust: same metrics per Trust
By GP practice (Table 5, Excel): ~305–360 practices, 2009/10 to present
- Disease Registers (17):
Asthma, Atrial Fibrillation, Cancer, Chronic Kidney Disease, Chronic Obstructive Pulmonary Disease, Coronary Heart Disease, Dementia, Depression, Diabetes Mellitus, Heart Failure 1, Heart Failure 3, Hypertension, Mental Health, Non-Diabetic Hyperglycaemia, Osteoporosis, Rheumatoid Arthritis, Stroke & TIA
- Data sources:
- PxStat (NI / LGD / HSCT levels):
DISPREVNI, DISPREVLGD, DISPREVHSCT matrices
- Excel workbook (GP-practice level — not in PxStat):
https://www.health-ni.gov.uk/topics/health-statistics/disease-prevalence
- Update Frequency:
Annual, approximately May of the following calendar year.
Example
>>> from bolster.data_sources.nisra import disease_prevalence as dp
>>> df = dp.get_latest_disease_prevalence()
>>> 'registered_patients' in df.columns
True
>>> 'prevalence_per_1000' in df.columns
True
Attributes
Functions
|
Get NI-wide annual disease prevalence (DISPREVNI). |
|
Get annual disease prevalence by Local Government District (DISPREVLGD). |
|
Get annual disease prevalence by HSC Trust (DISPREVHSCT). |
|
Get the latest NI disease prevalence data. |
|
Validate the disease prevalence DataFrame for internal consistency. |
Return the URL of the most recent disease prevalence Excel workbook. |
|
|
Parse Table 4 (GP practice details) into a lookup DataFrame. |
|
Parse all Table 5 sheets and return a concatenated long-format DataFrame. |
|
Fetch and return the latest GP-practice-level disease prevalence data. |
Module Contents
- bolster.data_sources.health_ni.disease_prevalence.get_ni_prevalence(force_refresh=False)[source]
Get NI-wide annual disease prevalence (DISPREVNI).
- Parameters:
force_refresh (bool) – Accepted for API compatibility but ignored; the PxStat API always returns the latest data without caching.
- Returns:
financial_year, year, disease, registered_patients, prevalence_per_1000.
- Return type:
DataFrame with columns
- bolster.data_sources.health_ni.disease_prevalence.get_lgd_prevalence(force_refresh=False)[source]
Get annual disease prevalence by Local Government District (DISPREVLGD).
- Parameters:
force_refresh (bool) – Accepted for API compatibility but ignored; the PxStat API always returns the latest data without caching.
- Returns:
financial_year, year, lgd, disease, registered_patients, prevalence_per_1000.
- Return type:
DataFrame with columns
- bolster.data_sources.health_ni.disease_prevalence.get_hsct_prevalence(force_refresh=False)[source]
Get annual disease prevalence by HSC Trust (DISPREVHSCT).
- Parameters:
force_refresh (bool) – Accepted for API compatibility but ignored; the PxStat API always returns the latest data without caching.
- Returns:
financial_year, year, trust, disease, registered_patients, prevalence_per_1000.
- Return type:
DataFrame with columns
- bolster.data_sources.health_ni.disease_prevalence.get_latest_disease_prevalence(force_refresh=False, level='ni', lcg=None)[source]
Get the latest NI disease prevalence data.
Fetches data from the NISRA PxStat API. The
levelparameter controls geographic granularity;lcgfilters to a specific Local Government District (when level=’lgd’).- Parameters:
force_refresh (bool) – Accepted for API compatibility but ignored; the PxStat API always returns the latest data without caching.
level (str) – Geographic level — ‘ni’ for NI-wide (default), ‘lgd’ for Local Government District breakdown, ‘trust’ for HSC Trust, or ‘gp’ for GP-practice-level data (sourced from Excel, not PxStat).
lcg (str | None) – Optional LGD name filter (used when level=’lgd’). If provided, only rows for that LGD are returned.
- Returns:
financial_year, year, disease, registered_patients, prevalence_per_1000. When level=’lgd’, also includes an ‘lgd’ column. When level=’trust’, also includes a ‘trust’ column.
- Return type:
DataFrame with columns
- Raises:
ValueError – If level is not one of ‘ni’, ‘lgd’, or ‘trust’.
Example
>>> df = get_latest_disease_prevalence() >>> 'registered_patients' in df.columns True >>> 'prevalence_per_1000' in df.columns True
- bolster.data_sources.health_ni.disease_prevalence.validate_disease_prevalence(df, level='ni')[source]
Validate the disease prevalence DataFrame for internal consistency.
- Parameters:
df (pandas.DataFrame) – DataFrame as returned by
get_latest_disease_prevalence().level (str) – Validation mode — ‘ni’ (default) or ‘lgd’/’trust’ for geographic breakdowns. Validates the ‘gp’ level alias for backward compatibility (treated same as ‘lgd’).
- Returns:
True if all checks pass.
- Raises:
NISRAValidationError – Describing the first failing check.
ValueError – If level is not a recognised value.
- Return type:
Example
>>> import pandas as pd >>> df = pd.DataFrame({ ... "year": [2017], "financial_year": ["2017/18"], ... "disease": ["Hypertension"], ... "registered_patients": [184824.0], ... "prevalence_per_1000": [102.9], ... }) >>> validate_disease_prevalence(df) True
- bolster.data_sources.health_ni.disease_prevalence.get_latest_publication_url()[source]
Return the URL of the most recent disease prevalence Excel workbook.
- Returns:
Absolute URL of the latest Excel workbook.
- Raises:
NISRADataNotFoundError – If the Excel link cannot be located.
- Return type:
Example
>>> url = get_latest_publication_url() >>> url.endswith(".xlsx") True
- bolster.data_sources.health_ni.disease_prevalence.parse_gp_practice_lookup(file_path, sheet_name=None)[source]
Parse Table 4 (GP practice details) into a lookup DataFrame.
- Parameters:
- Returns:
practice_code, practice_name, address, postcode.
- Return type:
DataFrame with columns
- Raises:
NISRADataNotFoundError – If the sheet cannot be found.
Example
>>> lkp = parse_gp_practice_lookup("/tmp/rdptd-tables-2026.xlsx") >>> "practice_code" in lkp.columns True >>> lkp["practice_code"].str.startswith("Z").all() True
- bolster.data_sources.health_ni.disease_prevalence.parse_all_gp_practices(file_path)[source]
Parse all Table 5 sheets and return a concatenated long-format DataFrame.
- Parameters:
file_path (str) – Path to the downloaded .xlsx workbook.
- Returns:
practice_code, practice_name, lcg, federation, financial_year, year, register, registered_patients, prevalence_per_1000.
- Return type:
Long-format DataFrame with columns
- Raises:
NISRADataNotFoundError – If no Table 5 sheets can be found or parsed.
Example
>>> df = parse_all_gp_practices("/tmp/rdptd-tables-2026.xlsx") >>> df["financial_year"].nunique() >= 17 True >>> df["practice_code"].nunique() >= 300 True
- bolster.data_sources.health_ni.disease_prevalence.get_latest_gp_prevalence(force_refresh=False)[source]
Fetch and return the latest GP-practice-level disease prevalence data.
Downloads the current Excel workbook from the Department of Health website (cached for one year), parses all Table 5 sheets, and returns a clean long-format DataFrame covering 2009/10 to the latest published year.
- Parameters:
force_refresh (bool) – If True, bypass the local file cache and re-download.
- Returns:
practice_code(str): GP practice identifier (e.g."Z00001")practice_name(str or None): Practice name from Table 4lcg(str or None): Local Commissioning Groupfederation(str or None): Federation name (None pre-2017/18)financial_year(str): e.g."2025/26"year(int): Start year of the financial yearregister(str): Disease register name (normalised)registered_patients(float): Patients on register at NPDprevalence_per_1000(float): Prevalence per 1,000 registered pts
- Return type:
Long-format DataFrame with columns
- Raises:
NISRADataNotFoundError – If the workbook cannot be located or downloaded.
NISRAValidationError – If the parsed data fails validation.
Example
>>> df = get_latest_gp_prevalence() >>> df["practice_code"].str.startswith("Z").all() True >>> df["financial_year"].nunique() >= 3 True