There is a need to develop a shared, robust understanding of the impact the shift to neighbourhood working will have on system sustainability. This is critical to making strategic decisions about future investment as a system, shifting activity from acute to community settings, and ensuring our model of care is sustainable and effective.
To support this, SEL ICS have partnered with PPL to develop a robust approach to modelling the benefits of Integrated Neighbourhood Teams (INTs). This work is being delivered through a blended team including SEL ICB BI, LGT PHM, and PPL drawing on SEL’s existing capabilities while adding capacity and technical expertise.
This report sets out the technical specification for implementing the modelling approach. It contains the core components required to build and run the model, including the underlying data specifications, metric definitions, and the data cleaning process. It also describes the analytical methods used to quantify effects, including regression models and related statistical experiments, as well as the approach to defining the INT cohorts. Finally, it documents the Monte Carlo simulation design that generates the end modelled impact of the INT inputs.
This initial modelling exercise focussed on:
Residents registered to a GP in South-East London with 3 or more long-term conditions. The table below displays the LTCs that were included.
| Long-Term Condition |
|---|
| Hypertension |
| Chronic Pain |
| Osteoarthritis |
| Diabetes |
| Depression |
| CKD (Chronic Kidney Disease) |
| Asthma |
| Coronary Heart Disease |
| Obesity |
| Atrial Fibrillation |
| Stroke and TIA |
| COPD (Chronic Obstructive Pulmonary Disease) |
| Heart Failure |
| Dementia |
| IBD (Inflammatory Bowel Disease) |
| Rheumatoid Arthritis |
| Peripheral Arterial Disease |
| Epilepsy |
| Bronchiectasis |
| Osteoporosis |
| Sarcoidosis |
| Liver Cirrhosis |
| Parkinson’s |
| SLE/Lupus |
| Multiple Sclerosis |
| Sickle Cell Disease |
| Cystic Fibrosis |
Residents registered to a GP in South-East London, aged 65+ living, and living with at least 1 long-term condition.
The current frailty definition reflects data quality concerns with the eFI and Rockwood scores. This definition will be reviewed and refined in the next phase of work.
If a resident meets both the MLTC and frailty definitions, they are assigned to the frailty cohort.
| Dataset | Source | Notes | Date range |
|---|---|---|---|
| General Practice | SEL BI Colleagues | Patient-level data containing demographic, LTC, counts of primary care activity, and health vulnerabilities. | Residents registeres at a SEL GP as of July 2025 |
| Non-Elective Inpatient Admissions | CDS v6.3 Type 130 | Episode-level data on NEL inpatient admissions, discharge, diagnosis, and ward. | Discharges between July 2023 - October 2025 |
| Outpatient Appointments | CDS V6-2 Type 020 | Episode-level data on outpatient appointments, referrals, services, attendance, and clinic | Appointments between July 2023 - June 2025 |
| Emergency Care Data | ECDS v4.0 | Episode-level data on emergency attendances, discharges, activity type, and departments | Attendances between July 2023 and June 2025 |
| Community Services Data | SEL BI Colleagues | Episode-level data on referrals, services, and providers | Service contact between July 2023 and June 2025 |
Datasets are linked using a Pseudonymised NHS Number :
SK_PATIENT_ID
The SEL BI team provided the following fields from primary care databases.
| Field name | Field description |
|---|---|
DATE_SNAPSHOT |
Date the dataset snapshot was taken (extract/snapshot date). |
SK_PATIENT_ID |
Pseudonymised unique patient identifier. |
DERIVED_GP_PRACTICE_CODE |
Derived GP practice code for the patient at the snapshot date. |
DERIVED_GP_PRACTICE_NAME |
Derived GP practice name for the patient at the snapshot date. |
GENDER_NAME |
Recorded gender. |
DATE_OF_BIRTH |
Date of birth. |
ETHNIC_CATEGORY_NAME |
Recorded ethnicity category. |
LSOA_NAME |
Lower Super Output Area (LSOA) name associated with the patient. |
IS_AFIB |
Flag indicating atrial fibrillation. |
IS_ASTHMA |
Flag indicating asthma. |
IS_CHD |
Flag indicating coronary heart disease. |
IS_CKD |
Flag indicating chronic kidney disease. |
IS_COPD |
Flag indicating chronic obstructive pulmonary disease. |
IS_DEMENTIA |
Flag indicating dementia. |
IS_DEPRESSION |
Flag indicating depression. |
IS_DIABETES |
Flag indicating diabetes. |
IS_EPILEPSY |
Flag indicating epilepsy. |
IS_HEART_FAILURE |
Flag indicating heart failure. |
IS_HYPERTENSION |
Flag indicating hypertension. |
IS_LD |
Flag indicating learning disability. |
IS_OSTEOPOROSIS |
Flag indicating osteoporosis. |
IS_PAD |
Flag indicating peripheral arterial disease. |
IS_PALCARE |
Flag indicating palliative care / on a palliative care register. |
IS_RARTH |
Flag indicating rheumatoid arthritis. |
IS_STROKE_OR_TIA |
Flag indicating stroke or transient ischaemic attack (TIA). |
IS_SMI |
Flag indicating severe mental illness. |
IS_OBESITY |
Flag indicating obesity. |
IS_SICKLE_CELL |
Flag indicating sickle cell disease. |
IS_BRONCHIECTASIS |
Flag indicating bronchiectasis. |
IS_CHRONIC_PAIN |
Flag indicating chronic pain. |
IS_LIVER_CIRRHOSIS |
Flag indicating liver cirrhosis. |
IS_CYSTIC_FIBROSIS |
Flag indicating cystic fibrosis. |
IS_IBD |
Flag indicating inflammatory bowel disease (IBD). |
IS_MULTIPLE_SCLEROSIS |
Flag indicating multiple sclerosis. |
IS_OSTEOARTHRITIS |
Flag indicating osteoarthritis. |
IS_PARKINSONS |
Flag indicating Parkinson’s disease. |
IS_SARCOIDOSIS |
Flag indicating sarcoidosis. |
IS_SLE_LUPUS |
Flag indicating systemic lupus erythematosus (SLE / lupus). |
IS_3_PLUS_LTC |
Flag indicating the patient has three or more long-term conditions. |
IS_FRAILTY |
Flag indicating frailty (per local frailty definition/score). |
IS_CARE_HOME |
Flag indicating care home resident status. |
COUNT_GP_APP_LAST_MONTH_ALL |
Count of all GP appointments in the last month. |
COUNT_GP_APP_LAST_3_MONTHS_ALL |
Count of all GP appointments in the last 3 months. |
COUNT_GP_APP_LAST_YEAR_ALL |
Count of all GP appointments in the last year. |
COUNT_GP_APP_LAST_2_YEARS_ALL |
Count of all GP appointments in the last 2 years. |
COUNT_GP_APP_LAST_MONTH_F2F |
Count of face-to-face GP appointments in the last month. |
COUNT_GP_APP_LAST_3_MONTHS_F2F |
Count of face-to-face GP appointments in the last 3 months. |
COUNT_GP_APP_LAST_YEAR_F2F |
Count of face-to-face GP appointments in the last year. |
COUNT_GP_APP_LAST_2_YEARS_F2F |
Count of face-to-face GP appointments in the last 2 years. |
COUNT_SMR_LAST_YEAR |
Count of structured medication reviews (SMR) in the last year. |
IS_BOWEL_SCREENING_UPTAKE |
Flag indicating bowel screening uptake (per defined eligibility/measurement window). |
IS_BREAST_SCREENING_UPTAKE |
Flag indicating breast screening uptake (per defined eligibility/measurement window). |
IS_CERVICAL_SCREENING_UPTAKE |
Flag indicating cervical screening uptake (per defined eligibility/measurement window). |
LATEST_BP_READING |
Most recent blood pressure reading value available at snapshot. |
LATEST_LDL_CHOL_READING |
Most recent LDL cholesterol reading value available at snapshot. |
LATEST_HBA1C_READING |
Most recent HbA1c reading value available at snapshot. |
COUNT_UNIQUE_MEDICATIONS_LAST_YEAR |
Number of unique medications prescribed/recorded in the last year. |
IS_CARER |
Flag indicating the patient is recorded as a carer. |
IS_ALCOHOL_SUBSTANCE_MISUSE |
Flag indicating alcohol and/or substance misuse concern. |
IS_SAFEGUARDING_CONCERN |
Flag indicating a safeguarding concern. |
IS_LANGUAGE_DIFFICULTY |
Flag indicating language/communication difficulty. |
IS_DISABLIITY |
Flag indicating disability (spelling as per source field). |
IS_SOCIALLY_MARGINALISED |
Flag indicating social marginalisation (per local definition). |
IS_REFUGEE |
Flag indicating refugee status (as recorded). |
IS_VIOLENCE_CONCERN |
Flag indicating a violence concern/risk flag. |
DATE_CASE_MANAGEMENT_START |
Date case management started (where applicable). |
DATE_CASE_MANAGEMENT_END |
Date case management ended (where applicable). |
COUNT_CASE_MANAGEMENT_START |
Count of case management starts in the defined period (as per source specification). |
COUNT_CASE_MANAGEMENT_END |
Count of case management ends in the defined period (as per source specification). |
IS_PROACTIVE_MDM |
Flag indicating proactive multidisciplinary management (MDM) activity. |
IS_LEWISHAM_INT_COHORT |
Flag indicating membership of the Lewisham INT cohort. |
IS_LEWISHAM_INT_DECLINED |
Flag indicating the patient declined Lewisham INT involvement. |
IS_LEWISHAM_INT_REVIEW |
Flag indicating a Lewisham INT review occurred / is due (per local definition). |
IS_GROUP_CONSULT_F2F |
Flag indicating face-to-face group consultation participation. |
IS_LIFESTYLE_MED_REVIEW |
Flag indicating a lifestyle medicine review occurred. |
The SEL BI team provided the following fields on non-elective inpatient spells.
| Field name | Field description |
|---|---|
SK_ENCOUNTER_ID |
Local surrogate key for the finished general episode / encounter record (project-specific identifier). |
SK_PATIENT_ID |
Pseudonymised patient identifier used to link records across datasets. |
RTT_PERIOD_STATUS |
Referral to Treatment (RTT) period status code for the patient’s RTT pathway (e.g., ongoing vs ended). |
DATE_RTT_PERIOD_START |
Start date of the RTT period. |
DATE_RTT_PERIOD_END |
End date of the RTT period (if the period has ended). |
CARER_SUPPORT_CODE |
Carer support indicator code (flag indicating whether carer support applies, using national codes where available). |
PATIENT_CLASSIFICATION_CODE |
Patient classification derived from admission method, intended management, and length of stay (e.g., day case vs ordinary admission). |
ADMISSION_METHOD_CODE |
Method of admission to the Hospital Provider Spell (coded; used in national reporting and grouping). |
SOURCE_OF_ADMISSION_CODE |
Source of admission to the Hospital Provider Spell (coded). |
DISCHARGE_DESTINATION_CODE |
Discharge destination from the Hospital Provider Spell (coded; includes destinations such as usual residence, temporary residence, etc.). |
DISCHARGE_METHOD_CODE |
Discharge method code from the Hospital Provider Spell (coded; legacy code set used in national processing/grouping). |
DATE_DISCHARGE |
Discharge date from the Hospital Provider Spell. |
IS_DISCHARGED_TO_HOME |
Derived flag indicating discharge destination corresponds to home/usual place of residence (project-derived). |
EPISODE_NUMBER |
Sequence number identifying the consultant episode within the Hospital Provider Spell (starts at 1 for each new admitted care episode). |
DATE_EPISODE_START |
Start date of the admitted care episode / consultant episode. |
DATE_EPISODE_END |
End date of the admitted care episode / consultant episode. |
REHABILITATION_DAYS |
Number of days recorded as rehabilitation-related (often used as a length-of-stay adjustment / reporting field). |
SPECIALIST_PALLIATIVE_CARE_DAYS |
Number of days recorded as specialist palliative care-related (often used as a length-of-stay adjustment / reporting field). |
CORE_HRG_CODE |
Core Healthcare Resource Group (HRG) code assigned via national grouping logic (used for costing and activity analysis). |
PRIMARY_DIAGNOSIS_CODE |
Primary diagnosis code for the episode (typically ICD-10 format in admitted care datasets). |
CARE_LOCATION_ID |
Local identifier for the care location within the provider (e.g., internal location/ward/bay identifier). |
LOCATION_SITE_CODE |
Provider site identifier where treatment/activity occurred (hospital site code / organisation site identifier). |
LOCATION_TYPE_CODE |
Code describing the type/class of location (project field; often aligns to national “location class”/location type concepts). |
WARD_INTENDED_CARE_INTENSITY |
Ward intended clinical care intensity code (level of resources/intensity of care intended to be provided in the ward). |
WARD_CODE |
Ward code identifying the ward where activity during the Hospital Provider Spell took place. |
The SEL BI team provided the following fields on outpatient appointments.
| Field | Field description |
|---|---|
SK_PATIENT_ID |
Pseudonymised patient identifier used for linkage. |
REFERRAL_TO_TREATMENT_PERIOD_STATUS_CODE |
Referral to Treatment (RTT) period status code (pathway status at the point of activity). |
DATE_REFERRAL_TO_TREATMENT_START |
Start date of the RTT period. |
DATE_REFERRAL_TO_TREATMENT_END |
End date of the RTT period. |
CARER_SUPPORT_INDICATOR_CODE |
Carer support indicator/code (whether support is available at normal residence). |
PRIMARY_DIAGNOSIS_CODE |
Primary diagnosis code (typically ICD-10). |
ATTENDANCE_STATUS_CODE |
Attendance status for the outpatient appointment (e.g. attended, DNA, cancelled). |
FIRST_ATTENDANCE_CODE |
Indicates first vs follow-up attendance (and related classifications, depending on coding). |
OUTPATIENT_ATTENDANCE_OUTCOME_CODE |
Outcome of the care professional outpatient attendance (e.g. discharged, follow-up planned). |
DATE_APPOINTMENT |
Date advised/recorded for the outpatient appointment. |
CORE_HRG_CODE |
Core Healthcare Resource Group (HRG) code assigned by grouping (currency for activity/resource use). |
SITE_CODE_OF_TREATMENT |
Organisation site code where the patient was treated (site within provider). |
ACTIVITY_LOCATION_CODE |
Activity location type code (e.g. outpatient clinic, ward, patient home). |
CLINIC_CODE |
Clinic identifier/code for where the appointment occurred. |
REFERRAL_PRIORITY_TYPE_CODE |
Referral priority type code (priority assigned to the referral). |
TREATMENT_FUNCTION_CODE |
Treatment function (specialty) code associated with the activity. |
The SEL BI team provided the following fields on emergency attendances.
| Field name | Field description |
|---|---|
SK_PATIENT_ID |
Pseudonymised patient identifier used to link records across datasets. |
ACCOMMODATION_STATUS_CODE |
Code describing the patient’s accommodation status at the time of attendance. |
PROVIDER_SITE_CODE_REPORTED |
Provider site code reported for where the emergency care activity took place. |
ACTIVITY_TYPE_CODE |
Code describing the type of emergency care activity or service setting. |
CONSULTATION_MECHANISM_CODE |
Code describing how the consultation was delivered, for example face to face or remote. |
ATTENDANCE_CATEGORY_CODE |
Code describing the category of attendance, for example new attendance or follow up. |
ATTENDANCE_SOURCE_CODE |
Code describing the source of attendance, for example self referral or referred by another service. |
DATETIME_ARRIVAL |
Date and time the patient arrived for emergency care. |
DATETIME_DEPARTURE |
Date and time the patient departed from emergency care. |
HRG_CODE |
Healthcare Resource Group (HRG) code assigned to the emergency care activity where available. |
CHIEF_COMPLAINT_CODE |
Code describing the chief complaint or presenting problem recorded for the attendance. |
PRIMARY_REFERRED_TO_CODE |
Code describing the primary service, specialty, or destination the patient was referred to from emergency care. |
DECISION_TO_ADMIT_TREATMENT_FUNCTION_CODE |
Treatment function code recorded at the decision to admit stage, representing the intended admitting specialty. |
DISCHARGE_STATUS_CODE |
Code describing the discharge status from emergency care, for example discharged, admitted, or transferred. |
DISCHARGE_DESTINATION_CODE |
Code describing the destination following discharge from emergency care, for example home, another provider, or another service. |
ORGANISATION_DISCHARGE_CODE |
Organisation code for the provider receiving the patient on discharge or transfer, where applicable. |
DISCHARGE_FOLLOW_UP_CODE |
Code indicating follow up arrangements following discharge, for example no follow up, GP follow up, or clinic follow up. |
The SEL BI team provided the following fields on community services.
| Field name | Field description |
|---|---|
SK_PATIENT_ID |
Pseudonymised patient identifier used to link records across datasets. |
FINANCIAL_YEAR |
Financial year associated with the referral record (e.g. 2024/25). |
FINANCIAL_MONTH |
Financial month within the financial year (typically 1–12) associated with the referral record. |
PROVIDER_NAME |
Name of the provider organisation delivering the service. |
SOURCE_OF_REFERRAL_NAME |
Source of referral (who/what service initiated the referral), as a descriptive label. |
REASON_FOR_REFERRAL_NAME |
Recorded reason for referral, as a descriptive label. |
SERVICE_REFERRED_TO_NAME |
Name/description of the community service the patient was referred to. |
IS_REJECTED_REFERRAL |
Binary flag indicating whether the referral was rejected (per local business rules/recording). |
ACSC admissions are used to identify non-elective inpatient admissions that can potentially be avoided with effective management and treatment such as improved primary or community health care services such as screening, vaccination, immunisation and health monitoring. Below are the ACSC conditions used in this piece of work.
kable(acsc_lkup)
| code | term |
|---|---|
| A35 | Other tetanus |
| A36 | Diphtheria |
| A37 | Whooping cough |
| A69 | Other spirochaetal infections |
| A80 | Acute poliomyelitis |
| B05 | Measles |
| B06 | Rubella [German measles] |
| B16 | Acute hepatitis B |
| B18 | Chronic viral hepatitis |
| B26 | Mumps |
| D50 | Iron deficiency anaemia |
| E10 | Type 1 diabetes mellitus |
| E11 | Type 2 diabetes mellitus |
| E12 | Malnutrition-related diabetes mellitus |
| E13 | Other specified diabetes mellitus |
| E14 | Unspecified diabetes mellitus |
| E40 | Kwashiorkor |
| E41 | Nutritional marasmus |
| E42 | Marasmic kwashiorkor |
| E43 | Unspecified severe protein-energy malnutrition |
| E55 | Vitamin D deficiency |
| E64 | Sequelae of malnutrition and other nutritional deficiencies |
| E86 | Volume depletion |
| G00 | Bacterial meningitis, not elsewhere classified |
| G40 | Epilepsy |
| G41 | Status epilepticus |
| H66 | Suppurative and unspecified otitis media |
| H67 | Otitis media in diseases classified elsewhere |
| I10 | Essential (primary) hypertension |
| I11 | Hypertensive heart disease |
| I20 | Angina pectoris |
| I24 | Other acute ischaemic heart diseases |
| I50 | Heart failure |
| J02 | Acute pharyngitis |
| J03 | Acute tonsillitis |
| J06 | Acute upper respiratory infections of multiple and unspecified sites |
| J10 | Influenza due to identified seasonal influenza virus |
| J11 | Influenza, virus not identified |
| J13 | Pneumonia due to Streptococcus pneumoniae |
| J14 | Pneumonia due to Haemophilus influenzae |
| J15 | Bacterial pneumonia, not elsewhere classified |
| J16 | Pneumonia due to other infectious organisms, not elsewhere classified |
| J18 | Pneumonia, organism unspecified |
| J20 | Acute bronchitis |
| J31 | Chronic rhinitis, nasopharyngitis and pharyngitis |
| J41 | Simple and mucopurulent chronic bronchitis |
| J42 | Unspecified chronic bronchitis |
| J43 | Emphysema |
| J44 | Other chronic obstructive pulmonary disease |
| J45 | Asthma |
| J46 | Status asthmaticus |
| J47 | Bronchiectasis |
| J81 | Pulmonary oedema |
| K02 | Dental caries |
| K03 | Other diseases of hard tissues of teeth |
| K04 | Diseases of pulp and periapical tissues |
| K05 | Gingivitis and periodontal diseases |
| K06 | Other disorders of gingiva and edentulous alveolar ridge |
| K08 | Other disorders of teeth and supporting structures |
| K09 | Cysts of oral region, not elsewhere classified |
| K12 | Stomatitis and related lesions |
| K13 | Other diseases of lip and oral mucosa |
| K25 | Gastric ulcer |
| K26 | Duodenal ulcer |
| K27 | Peptic ulcer, site unspecified |
| K28 | Gastrojejunal ulcer |
| K52 | Other noninfective gastroenteritis and colitis |
| L03 | Cellulitis |
| L04 | Acute lymphadenitis |
| L08 | Other local infections of skin and subcutaneous tissue |
| L88 | Pyoderma gangrenosum |
| L98 | Other disorders of skin and subcutaneous tissue, not elsewhere classified |
| M01 | Direct infections of joint in infectious and parasitic diseases classified elsewhere |
| N10 | Acute tubulo-interstitial nephritis |
| N11 | Chronic tubulo-interstitial nephritis |
| N12 | Tubulo-interstitial nephritis, not specified as acute or chronic |
| N13 | Obstructive and reflux uropathy |
| N70 | Salpingitis and oophoritis |
| N73 | Other female pelvic inflammatory diseases |
| N74 | Female pelvic inflammatory disorders in diseases classified elsewhere |
| O15 | Eclampsia |
| R02 | Gangrene, not elsewhere classified |
| R56 | Convulsions, not elsewhere classified |
The next phase of this work will identify other forms of avoidable activity that can be identified using ICD-10 codes, including alcohol-related admissions and falls-related admissions.
Acute activity was costed using the 2025 to 2026 NHS Payment Scheme and the published pay award prices workbook. Episode level costs were derived by mapping each record’s HRG code to the corresponding national price.
The
Index
of Multiple Deprivation (2025) was added to the General Practice
dataset on Lower Super Output Area name. specifically
LSOA_NAME in the primary care extract matched to LSOA
name (2021) in the IMD lookup. Where no match is found, the IMD
field will remain missing.
# primary_care <- read.csv(primary_care_file_path, colClasses = "character", stringsAsFactors = FALSE)
#
# primary_care <- primary_care %>%
# left_join(
# imd %>% select(`LSOA code (2021)`,
# `LSOA name (2021)`,
# `Local Authority District name (2024)`,
# `Index of Multiple Deprivation (IMD) Score`),
# join_by(LSOA_NAME == `LSOA name (2021)`)
# )
Episode start and end dates were converted from date time formats into standard Date fields. This ensures consistent calculations when deriving lengths of stay and when aggregating episodes into admissions.
The first three characters of PRIMARY_DIAGNOSIS_CODE
were extracted to create an ICD10 category field. This ICD10 category
was joined to the ACSC lookup to identify whether each spell relates to
an Ambulatory Care Sensitive Condition, with acsc set to 1
where a match is found and 0 otherwise, and the mapped condition name
stored in acsc_term.
A set of commissioning and activity classification fields were converted from coded values into descriptive labels by joining to relevant lookup tables. This includes RTT period status, carer support, patient classification, admission method, source of admission, discharge destination, and discharge method. HRG codes were also joined to the HRG tariff lookup to bring in spell level cost parameters.
kable(rtt_period_status_lkp)
| RTT_PERIOD_STATUS | rtt_period_status_desc |
|---|---|
| NA | |
| 10 | First activity in an RTT period |
| 20 | Subsequent activity in RTT period – further activity expected |
| 21 | Subsequent activity in RTT period at another provider (transfer) |
| 30 | End RTT: first definitive treatment started |
| 31 | End RTT: active monitoring started – patient-initiated |
| 32 | End RTT: active monitoring started – clinician-initiated |
| 33 | End RTT: patient did not attend first care activity |
| 34 | End RTT: decision not to treat / no further contact required |
| 35 | End RTT: patient declined offered treatment |
| 90 | Not in RTT: activity after first definitive treatment |
| 91 | Not in RTT: activity during active monitoring |
| 92 | Not in RTT: diagnostic tests by GP before referral |
| 98 | Not in RTT: activity not applicable to RTT periods |
| 99 | RTT period status not yet known |
kable(carer_support_lkp)
| CARER_SUPPORT_CODE | carer_support_desc |
|---|---|
| NA | |
| 01 | Carer support available at normal residence |
| 02 | Carer support not available at normal residence |
kable(patient_classification_lkp)
| PATIENT_CLASSIFICATION_CODE | patient_classification_desc |
|---|---|
| 1 | Ordinary admission (incl. elective expected to stay ≥1 night) |
| 2 | Day case admission |
| 3 | Regular day admission (planned series, discharged same day) |
| 4 | Regular night admission (planned series, discharged next morning) |
| 8 | Not applicable |
kable(admission_method_lkp)
| ADMISSION_METHOD_CODE | admission_method_desc |
|---|---|
| 21 | Emergency: via this provider’s A&E or dental casualty |
| 22 | Emergency: GP request direct to provider |
| 23 | Emergency: via bed bureau |
| 24 | Emergency: via consultant clinic (this or another provider) |
| 25 | Emergency: via mental health crisis resolution team |
| 28 | Emergency: other means (legacy aggregated category) |
| 2A | Emergency: A&E of another provider – not admitted there |
| 2B | Emergency: transfer of admitted patient from another provider |
| 2C | Emergency: baby born at home as intended |
| 2D | Emergency: other emergency admission |
kable(source_of_admission_lkp)
| SOURCE_OF_ADMISSION_CODE | source_of_admission_desc |
|---|---|
| NA | |
| 19 | Usual place of residence (incl. wardened accommodation / no fixed abode) |
| 29 | Temporary residence (e.g. hotel, residential education) |
| 37 | Court |
| 39 | Penal establishment, court or police facility (legacy combined code) |
| 42 | Police station / police custody suite |
| 49 | NHS other provider – high security psychiatric accommodation |
| 51 | NHS other provider – general ward / younger physically disabled / ED |
| 52 | NHS other provider – maternity or neonatal ward |
| 53 | NHS other provider – mental health or learning disability ward |
| 54 | NHS-run care home |
| 55 | Care home services with nursing |
| 56 | Care home services without nursing |
| 65 | Local authority residential accommodation where care is provided |
| 66 | Local authority foster care |
| 79 | Babies born in or on the way to hospital |
| 85 | Non-NHS (excluding LA) run care home |
| 87 | Non-NHS run hospital |
| 88 | Non-NHS (excluding LA) run hospice |
| 98 | Not applicable |
| 99 | Source of admission not known |
kable(discharge_destination_lkp)
| DISCHARGE_DESTINATION_CODE | discharge_destination_desc |
|---|---|
| NA | |
| 19 | Usual place of residence (incl. wardened accommodation / no fixed abode) |
| 29 | Temporary place of residence (e.g. hotel, residential education) |
| 30 | Repatriation from high-security psychiatric accommodation in NHS provider |
| 37 | Court |
| 38 | Penal establishment or police station (legacy combined code) |
| 42 | Police station / police custody suite |
| 48 | High-security psychiatric hospital, Scotland |
| 49 | NHS other provider – high-security psychiatric accommodation |
| 50 | NHS other provider – medium secure unit |
| 51 | NHS other provider – general ward / younger physically disabled |
| 52 | NHS other provider – maternity or neonatal ward |
| 53 | NHS other provider – mental health or learning disability ward |
| 54 | NHS-run care home |
| 55 | Care home services with nursing |
| 56 | Care home services without nursing |
| 65 | Local authority residential accommodation where care is provided |
| 66 | Local authority foster care |
| 79 | Patient died or stillbirth |
| 84 | Independent sector provider-run hospital – medium secure unit |
| 85 | Non-NHS (excluding LA) run care home |
| 87 | Independent sector provider-run hospital (excl. medium secure) |
| 88 | Hospice (non-NHS, excl. LA) |
| 98 | Not applicable – spell not finished / current episode unfinished |
| 99 | Destination of discharge not known |
kable(discharge_method_lkp)
| DISCHARGE_METHOD_CODE | discharge_method_desc |
|---|---|
| NA | |
| 1 | Discharged on clinical advice or with clinical consent |
| 2 | Self-discharge or discharged by relative/advocate |
| 3 | Discharged by MH review tribunal, Home Secretary or court |
| 4 | Patient died |
| 6 | Self-discharge (extra granularity for MH datasets) |
| 7 | Discharged by relative/advocate (extra granularity for MH datasets) |
| 8 | Not applicable – spell not finished / episode unfinished |
| 9 | Discharge method not known |
Spell level records were aggregated to a single admission record
using SK_ENCOUNTER_ID. For each encounter, the earliest
episode start date and latest discharge date were retained, and key
descriptive fields and cost parameters were carried forward to the
admission level dataset.
Admissions with invalid episode start dates were removed. Bed days were calculated as the difference between discharge date and episode start date, and trimmed bed days were derived by subtracting the HRG trim point and setting negative values to zero. Total cost was then calculated as the base non elective spell cost plus the per day long stay payment applied to trimmed bed days.
# inpatient <- read.csv(inpatient_file_path, colClasses = "character", stringsAsFactors = FALSE)
#
# #Clean NEL Inpatient
# inpatient_clean <- inpatient %>%
#
# #Clean Dates
# mutate(DATE_EPISODE_START = as.Date(as.POSIXct(DATE_EPISODE_START, format = "%Y-%m-%d %H:%M:%OS")),
# DATE_EPISODE_END = as.Date(as.POSIXct(DATE_EPISODE_END, format = "%Y-%m-%d %H:%M:%OS")),
# DATE_DISCHARGE = as.Date(DATE_DISCHARGE))%>%
#
# #Identify ACSC
# mutate(icd10 = substr(PRIMARY_DIAGNOSIS_CODE, 1, 3)) %>%
# left_join(acsc_lkup, join_by(icd10 == code)) %>%
# mutate(acsc = if_else(is.na(term), 0, 1)) %>%
# dplyr::rename(acsc_term = term) %>%
#
# #Map commissioning variables
# left_join(rtt_period_status_lkp, by = "RTT_PERIOD_STATUS") %>%
# left_join(carer_support_lkp, by = "CARER_SUPPORT_CODE") %>%
# left_join(patient_classification_lkp, by = "PATIENT_CLASSIFICATION_CODE") %>%
# left_join(admission_method_lkp, by = "ADMISSION_METHOD_CODE") %>%
# left_join(source_of_admission_lkp, by = "SOURCE_OF_ADMISSION_CODE") %>%
# left_join(discharge_destination_lkp, by = "DISCHARGE_DESTINATION_CODE") %>%
# left_join(discharge_method_lkp, by = "DISCHARGE_METHOD_CODE") %>%
# left_join(apc_hrg_tarrif, join_by(CORE_HRG_CODE == `HRG Code`)) %>%
#
# #Aggregate Data from spell/encounter level to admission level
# group_by(SK_ENCOUNTER_ID) %>%
# summarise(
# SK_PATIENT_ID = unique(SK_PATIENT_ID),
# DATE_EPISODE_START = min(DATE_EPISODE_START, na.rm=T),
# DATE_DISCHARGE = max(DATE_DISCHARGE, na.rm=T),
# rtt_period_status_desc = unique(rtt_period_status_desc),
# carer_support_desc = unique(carer_support_desc),
# patient_classification_desc = unique(patient_classification_desc),
# admission_method_desc = unique(admission_method_desc),
# source_of_admission_desc = unique(source_of_admission_desc),
# DISCHARGE_DESTINATION_CODE = unique(DISCHARGE_DESTINATION_CODE),
# discharge_method_desc = unique(discharge_method_desc),
# IS_DISCHARGED_TO_HOME = unique(IS_DISCHARGED_TO_HOME),
# REHABILITATION_DAYS = unique(REHABILITATION_DAYS),
# SPECIALIST_PALLIATIVE_CARE_DAYS = unique(SPECIALIST_PALLIATIVE_CARE_DAYS),
# CORE_HRG_CODE = unique(CORE_HRG_CODE),
# PRIMARY_DIAGNOSIS_CODE = unique(PRIMARY_DIAGNOSIS_CODE),
# icd10 = unique(icd10),
# acsc = unique(acsc),
# acsc_term = unique(acsc_term),
# episode_care_locations = max(CARE_LOCATION_ID),
# `Non-elective spell (£)` = unique(`Non-elective spell (£)`),
# `Non-elective long stay trim point (days)` = unique(`Non-elective long stay trim point (days)`),
# `Per day long stay payment elective non-elective (for days exceeding trim point) (£)` = unique(`Per day long stay payment elective non-elective (for days exceeding trim point) (£)`)
# ) %>%
#
# #Assign Cost
# filter(!DATE_EPISODE_START == Inf) %>%
# mutate(bed_days = as.integer(DATE_DISCHARGE - DATE_EPISODE_START),
# bed_days_trim = bed_days- `Non-elective long stay trim point (days)`,
# bed_days_trim = if_else(bed_days_trim<0,0,bed_days_trim),
# cost = `Non-elective spell (£)` + bed_days_trim * `Per day long stay payment elective non-elective (for days exceeding trim point) (£)`)
Key date fields were converted into standard Date formats, including
DATE_REFERRAL_TO_TREATMENT_START,
DATE_REFERRAL_TO_TREATMENT_END, and
DATE_APPOINTMENT. TREATMENT_FUNCTION_CODE was
also converted to a numeric field to support consistent joining to
tariff and lookup tables.
A set of coded outpatient fields were mapped to descriptive labels by joining to the relevant lookup tables. This includes RTT period status, carer support indicator, attendance status, first attendance, and outpatient attendance outcome.
kable(attendance_status_lookup)
| ATTENDANCE_STATUS_CODE | attendance_status_desc |
|---|---|
| Missing / not recorded | |
| 2 | APPOINTMENT cancelled by, or on behalf of, the PATIENT |
| 3 | Did not attend – no advance warning given |
| 4 | APPOINTMENT cancelled or postponed by the Health Care Provider |
| 5 | Attended on time or, if late, before CARE PROFESSIONAL was ready to see the PATIENT |
| 6 | Arrived late, after CARE PROFESSIONAL was ready, but was seen |
| 7 | PATIENT arrived late and could not be seen |
| 0 | Not applicable – APPOINTMENT occurs in the future (Future OP only, may not appear) |
kable(first_attendance_lookup)
| FIRST_ATTENDANCE_CODE | first_attendance_desc |
|---|---|
| Missing / not recorded | |
| 1 | First attendance face to face |
| 2 | Follow-up attendance face to face |
| 3 | First telephone or Telemedicine consultation |
| 4 | Follow-up telephone or Telemedicine consultation |
| 5 | Referral To Treatment Clock Stop Administrative Event |
kable(outpatient_outcome_lookup)
| OUTPATIENT_ATTENDANCE_OUTCOME_CODE | outpatient_attendance_outcome_desc |
|---|---|
| Missing / not recorded | |
| 1 | PATIENT discharged from care of CARE PROFESSIONAL without Personalised OP Follow Up |
| 2 | PATIENT given a timed OP follow up at this attendance (no Personalised OP Follow Up) |
| 3 | PATIENT to be given a timed OP follow up at a later date (no Personalised OP Follow Up) |
| 4 | PATIENT moved to a Personalised Out-Patient Follow Up Pathway |
| 5 | PATIENT discharged to a Personalised Out-Patient Follow Up Pathway |
Where remote attendance HRG variants were present, these were mapped
to their face-to-face equivalents to ensure consistent costing. This was
applied by replacing the relevant HRG codes within
CORE_HRG_CODE prior to applying tariff lookups.
The NHS payments scheme has various lookups on costing outpatient
episodes with different lookups for appointments, procedures, and
‘unbundled’ activity. A column was added to the outpatient data for each
lookup using TREATMENT_FUNCTION_CODE and
CORE_HRG_CODE. Treatment function codes were also mapped to
descriptive labels through the relevant lookup.
Appointment level cost was derived using a stepped fallback approach. Where an outpatient tariff value was available it was used with treatment function code, otherwise costs fell back to the outpatient procedure price, then the combined day case or ordinary elective spell price, then any supplementary HRG based cost, and finally zero where no price could be assigned.
Waiting time was calculated as the difference between
DATE_REFERRAL_TO_TREATMENT_END and
DATE_REFERRAL_TO_TREATMENT_START.
Records flagged as referral to treatment clock stop administrative
events were removed using FIRST_ATTENDANCE_CODE.
Appointments that did not take place were excluded based on
ATTENDANCE_STATUS_CODE, removing cancelled and non-attended
statuses as well as blank or invalid values.
# outpatient <- read.csv(outpatient_file_path, colClasses = "character", stringsAsFactors = FALSE)
#
# # Clean Outpatient
# outpatient_clean <- outpatient %>%
#
# #Clean Raw Variables
# mutate(DATE_REFERRAL_TO_TREATMENT_START = as.Date(DATE_REFERRAL_TO_TREATMENT_START),
# DATE_REFERRAL_TO_TREATMENT_END = as.Date(DATE_REFERRAL_TO_TREATMENT_END),
# DATE_APPOINTMENT = as.Date(DATE_APPOINTMENT),
# TREATMENT_FUNCTION_CODE = as.numeric(TREATMENT_FUNCTION_CODE))%>%
#
# #Join lookups
# left_join(rtt_outpatient_lookup,
# by = "REFERRAL_TO_TREATMENT_PERIOD_STATUS_CODE") %>%
# left_join(carer_support_lookup,
# by = "CARER_SUPPORT_INDICATOR_CODE") %>%
# left_join(attendance_status_lookup,
# by = "ATTENDANCE_STATUS_CODE") %>%
# left_join(first_attendance_lookup,
# by = "FIRST_ATTENDANCE_CODE") %>%
# left_join(outpatient_outcome_lookup,
# by = "OUTPATIENT_ATTENDANCE_OUTCOME_CODE") %>%
#
# #Cost remote same as f2f
# mutate(CORE_HRG_CODE = gsub("WF01C", "WF01A",
# gsub("WF01D", "WF01B",
# gsub("WF02C", "WF02A",
# gsub("WF02D","WF02B", CORE_HRG_CODE))))) %>%
#
# #Cost lookups
# left_join(outpatient_hrg_tarrif %>% select(CORE_HRG_CODE, `Treatment function code`, value),
# join_by(CORE_HRG_CODE == CORE_HRG_CODE, TREATMENT_FUNCTION_CODE == `Treatment function code`)) %>%
# left_join(apc_hrg_tarrif %>% select(`HRG Code`, `HRG Name`, `Outpatient procedure (£)`, `Combined day case /ordinary elective spell (£)`),
# join_by(CORE_HRG_CODE == `HRG Code`)) %>%
# left_join(hrg_extra,
# join_by(CORE_HRG_CODE == `HRG Code`)) %>%
# left_join(treatment_function_code_lkup,
# join_by(TREATMENT_FUNCTION_CODE == Code)) %>%
#
# #Cost Appointments
# mutate(`Outpatient procedure (£)` = as.numeric(`Outpatient procedure (£)`)) %>%
# mutate(`Combined day case /ordinary elective spell (£)` = as.numeric(`Combined day case /ordinary elective spell (£)`)) %>%
# mutate(COST = if_else(is.na(value), `Outpatient procedure (£)`, value)) %>%
# mutate(COST = if_else(is.na(COST), `Combined day case /ordinary elective spell (£)`, COST)) %>%
# mutate(COST = if_else(is.na(COST), extra_cost, COST)) %>%
# mutate(COST = if_else(is.na(COST), 0, COST)) %>%
#
# #Filter out referral to treatment clock stop administrative event
# filter(!FIRST_ATTENDANCE_CODE %in% c("5")) %>%
#
# #Filter out appointments that did not occur
# filter(!ATTENDANCE_STATUS_CODE %in% c("1","2","3","4","7","0", "")) %>%
#
# #Calculate Days Waiting
# mutate(days_waiting = DATE_REFERRAL_TO_TREATMENT_END - DATE_REFERRAL_TO_TREATMENT_START)%>%
#
# #Select Relevant Variables
# select(SK_PATIENT_ID,DATE_REFERRAL_TO_TREATMENT_START, DATE_REFERRAL_TO_TREATMENT_END, DATE_APPOINTMENT,Description, rtt_status_desc, carer_support_desc, attendance_status_desc, first_attendance_desc, outpatient_attendance_outcome_desc, COST, days_waiting, SITE_CODE_OF_TREATMENT, ACTIVITY_LOCATION_CODE, CLINIC_CODE)
Arrival and departure timestamps were converted from date time
formats into standard Date fields using DATETIME_ARRIVAL
and DATETIME_DEPARTURE. This provides a consistent basis
for downstream aggregation and time based calculations.
Core ECDS coded fields were mapped to descriptive labels by joining to the relevant lookup tables. This includes activity type, attendance category, consultation mechanism, and decision to admit treatment function.
The ED HRG tariff lookup was joined using HRG_CODE to
bring in the HRG name and the relevant national price field for Type 1
and Type 2 Emergency Care Departments.
A defined set of SNOMED coded fields was converted into descriptions,
including accommodation status, attendance source, chief complaint,
primary referred to, discharge status, discharge destination, and
discharge follow up. A single description per conceptId was
selected from the SNOMED description table and then joined to the
dataset for each SNOMED coded field.
# ecds <- read.csv(ed_file_path, colClasses = "character", stringsAsFactors = FALSE)
#
# #Clean ECDS
# ecds_clean <- ecds %>%
# #Clean Dates
# mutate(DATETIME_ARRIVAL = as.Date(as.POSIXct(DATETIME_ARRIVAL, format = "%Y-%m-%d %H:%M:%OS")),
# DATETIME_DEPARTURE = as.Date(as.POSIXct(DATETIME_DEPARTURE, format = "%Y-%m-%d %H:%M:%OS")))%>%
# left_join(ecds_activity_type_lu, by = "ACTIVITY_TYPE_CODE") %>%
# left_join(ecds_attendance_category_lu, by = "ATTENDANCE_CATEGORY_CODE") %>%
# left_join(ecds_consultation_mechanism_lu, by = "CONSULTATION_MECHANISM_CODE") %>%
# left_join(ecds_decision_to_admit_tfc_lu,
# by = "DECISION_TO_ADMIT_TREATMENT_FUNCTION_CODE") %>%
# left_join(ed_hrg_tarrifs %>% select(`HRG code`, `HRG name`, `Type 1 and 2 Emergency Care Departments`),
# join_by(HRG_CODE == `HRG code`))
#
# #Snomed Vars
# snomed_vars <- c("ACCOMMODATION_STATUS_CODE", "ATTENDANCE_SOURCE_CODE", "CHIEF_COMPLAINT_CODE","PRIMARY_REFERRED_TO_CODE", "DISCHARGE_STATUS_CODE", "DISCHARGE_DESTINATION_CODE", "DISCHARGE_FOLLOW_UP_CODE")
#
# set.seed(123)
#
# snomed_desc_select <- snomed_desc %>%
# group_by(conceptId) %>%
# slice_sample(n = 1)
#
# for(i in snomed_vars){
# ecds_clean <- ecds_clean %>%
# mutate(!!as.name(i) := as.integer(!!as.name(i))) %>%
# left_join(snomed_desc_select, join_by(!!as.name(i) == conceptId)) %>%
# dplyr::rename(!!as.name(gsub("_CODE", "", i)) := term)
# }
A single Date field was created by converting the financial year and financial month fields into a calendar date.
# csds <- read.csv(cs_file_path,colClasses = "character",stringsAsFactors=FALSE)
#
# csds_clean <- csds %>%
# mutate(
# fy_start = as.integer(substr(FINANCIAL_YEAR, 1, 4)), # e.g. "2023-24" -> 2023
# year_for_date = if_else(
# str_detect(FINANCIAL_MONTH, "-Jan|-Feb|-Mar"),
# fy_start + 1L, # Jan–Mar belong to the *next* calendar year
# fy_start # Apr–Dec belong to the start year
# ),
# DATE = as.Date(
# paste0(FINANCIAL_MONTH, "-", year_for_date),
# format = "%d-%b-%Y"
# )
# ) %>%
# select(-fy_start, -year_for_date)
The model integrates three linked components. The demand model projects how neighbourhood working changes health and care demand, activity, and patient flow. The capacity model translates these projected shifts into workforce implications, reflecting neighbourhood team design and wider workforce constraints. The financial impact model then converts demand and capacity outputs into financial projections, supporting commissioner and provider perspectives and enabling analysis of how savings are realised in practice.
The model is built around a set of modelling propositions. These are statements about how we believe the system works, expressed in a way that can be represented within the model. They provide a structured way to translate engagement, evidence, and analytical insight into modelling choices, and they make clear which elements of the model are fixed design decisions and which are treated as uncertain assumptions.
Structural propositions define the structure of the model and how activity is represented. They describe the rules and mechanisms that shape the simulation, such as how residents are cohorted, how risk stratification is applied, how non demographic growth is incorporated, and how primary and community activity growth and unmet need are represented. In practice, these propositions determine what pathways exist in the model and what transformations are applied to baseline activity.
Parametric propositions define the values used within that structure. They translate a proposition into a parameter or distribution that can be sampled within the Monte Carlo simulation, such as the estimated effect of an INT activity mitigator on admissions, attendances, or bed days. These parameters can be informed by regression models, statistical experiments, or published evidence, and are updated as better information becomes available.
Please use pan and zoom to navigate the flowchart.
The following table provides a structured summary of the modelling propositions used to specify and develop the INT model. Each row describes what will be represented in the model, and where it sits within the overall workflow.
| Model Item | Module | Proposition Type | Proposition Description |
|---|---|---|---|
| SEL001 - INTs will use Risk Stratification on their population segments to identify a proactive target cohort | Core | Structural |
This is a Structural Proposition. It requires the modelling team to
build risk stratification into the modelling approach to accurately
identify the residents that will be targeted by each place.
The Risk Stratification Algorithm used by the Lewisham and Greenwich PHM team was rebuilt and applied to the segments in each place. |
| SEL003 - INTs will provide high-risk individuals with more GP contacts if their needs are not currently met by primary care. These GP contacts will reduce their chance of a NEL admission | Core | Structural + Proposition |
Proposition:
A statistical experiment designed around risk of NEL admission regression found that , for the frailty and MLTC cohort, each GP contact reduces the chance of a NEL admission by 0.8%. The regression considered dependant variables around demographic, LTCs, social determinants, and previous care activity. Structural: If a member of the INT cohort has less F2F GP contacts than the medium number of contacts for their risk group, the difference in GP contacts is “given” to them with the derived mitigator effect. |
| SEL004 - INTs will provide structured medication reviews and optimisation to those who meet criteria (e.g. 8+ medications). This will lead to an expected reduction in unplanned acute activity | Core | Proposition |
Direct Activity Mitigator.
Propensity Score Matching was used to match residents who had a structured medication review in the last year with those that did not based on their demographics, LTCs, social determinants, and health care activity. A statistical comparison in the difference in NEL admissions between the first and second year of data found that a SMR reduces the chance of a NEL admission by 3.8% |
| SEL005 - INTs identify patients who have high ‘outpatient fragmentation’ and help to rationalise their care and thereby reduce the number of outpatient contacts | Core | Structural |
The model will calculate the outpatient fragmentation of each resident
in out cohorts. The model will calculate the necessary reduction for
each patient to have a median outpatient fragmentation score based on
their risk.
Research paper used to calculate outpatient fragmentation: https://bmjopen.bmj.com/content/9/3/e022965 |
| SEL002 - INTs will apply their proactive capacity across different risk groups. | Workforce | Structural |
The modelling team learnt from engagement that INTs may not proactively
target the highest risk individuals as they may have a lot of
community/neighbourhood care already in place.
Each place will be able to enter the number of residents they are proactively aiming to target in the next year. Each place will be able to define high risk and a medium risk cohorts. Each place will be able to set how much of their capacity they want to use on the medium and high risk groups. |
Placeholder
Placeholder
Placeholder
Placeholder
Placeholder
| Date | Version | Change |
|---|---|---|
| 2026-01-05 | v0.1 | Data Specs and Data Cleaning |