Calculate outcomes#
This notebook calculates outcomes based on travel times from Lower Super Output Areas (LSOAs) to nearest (in time) acute stroke units that provide thrombolysis and/or thrombectomy.
This notebook calculates the outcomes using the stroke outcome model. The following notebooks combine different cohorts of patients to find the results for a mixed population, and then further notebooks plot the results.
Plain English summary#
We would like to know how travel time to stroke units affects patient outcomes for different parts of England and Wales. We can explore this by keeping the same timings for everything else between the start of the stroke and the beginning of treatment and only adjusting the travel time. For example, a patient who lives 20 minutes further away from the stroke unit than another patient will have an onset to treatment time 20 minutes longer.
In this notebook we look at each Lower Super Output Area (LSOA), a small region of the country that contains a couple of thousand people. For an idea of scale, the city of Exeter is split into around 70 or 80 LSOA. In a more rural location, a larger geographical area must be covered to collect a couple of thousand people and so the LSOAs are larger.
We find a few travel times:
the travel time from each LSOA to its nearest stroke unit
the travel time from each LSOA to its nearest thrombectomy unit
the travel time between each LSOA’s nearest stroke unit and its nearest thrombectomy unit, for transfers between hospitals
We then add these to fixed stroke pathway times to calculate a few times to treatment:
time to IVT when travelling directly to the nearest stroke unit
time to MT after a transfer from the nearest stroke unit to the MT unit
time to IVT when travelling directly to the MT unit
time to MT when travelling directly to the MT unit
In the UK most of the stroke units will provide thrombolysis but not thrombectomy. Some patients will live nearest to an MT unit and so both of their sets of times will be identical. For most patients though, the time to IVT will be longer if travelling to the MT unit because the unit is further away than their nearest unit. The time to MT is usually longer if a transfer is required than if the patient went directly to the MT unit to start with, partly because the patient spends more time travelling between units and partly because there are delays in getting the patient ready to travel between hospitals.
We can then feed these treatment times into the stroke outcome model. This will give us two sets of outcomes for patients in each LSOA in England and Wales: one set for patients who travel directly to the nearest stroke unit, and a second set for patients who travel directly to the MT centre.
Aims#
Calculate outcomes after treatment for these cohorts:
nLVO with IVT
LVO with IVT only
LVO with MT only
LVO with both IVT and MT
Calculate outcomes after treatment for these timings:
IVT at the nearest stroke unit
MT after transfer to the MT unit
IVT after redirection to the MT unit
MT after redirection to the MT unit
Then save the outcome data to file for later use.
Two sets of outcomes will be saved:
population-averaged added utility, shift in mean mRS, proportion with mRS<=2
mRS distribution after treatment
Method#
The travel times are calculated from each LSOA centroid to the location of each stroke unit.
Travel times are estimated using Open Street Map[1], accessed by routino [2].
[1] https://www.openstreetmap.org/
[2] https://packages.debian.org/sid/routino
load in stroke-map package
Calculate travel time from each LSOA to its nearest acute stroke unit and to its nearest unit providing thrombectomy
Add on fixed pathway timings (onset to call, ambulance on scene, door-in-door-out etc.) to find time to thrombolysis and time to thrombectomy
Feed treatment times into the outcome model to find outcomes for each patient subgroup at those treatment times.
Load packages#
import numpy as np
import pandas as pd
import copy
import os
import warnings
warnings.filterwarnings("ignore")
dir_output = 'output'
# Adjust max rows to show
pd.set_option('display.max_rows', 100)
import stroke_maps
import stroke_outcome
import stroke_outcome.outcome_utilities
stroke_maps.__version__
'0.5.0'
stroke_outcome.__version__
'0.1.6'
import stroke_maps.load_data
import stroke_maps.catchment
from stroke_outcome.continuous_outcome import Continuous_outcome
Global variables to use#
limit_to_england = False
# File name for saved results
file_name = 'lsoa_base'
Load and parse data#
Load and parse hospital data#
# Get list of hopsitals and limit to those used in 2022
hospitals = stroke_maps.load_data.stroke_unit_region_lookup()
hospitals['use'] = hospitals[['use_ivt', 'use_mt']].max(axis=1)
mask = hospitals['use'] == 1
hospitals = hospitals[mask]
if limit_to_england:
mask = hospitals['country'] == 'England'
hospitals = hospitals[mask]
hospitals.head()
stroke_team | short_code | ssnap_name | use_ivt | use_mt | use_msu | transfer_unit_postcode | lsoa | lsoa_code | region | region_code | region_type | country | icb | icb_code | isdn | use | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
postcode | |||||||||||||||||
SY231ER | Bronglais Hospital (Aberystwyth) | AB | Bronglais Hospital | 1 | 0 | 0 | nearest | Ceredigion 002A | W01000512 | Hywel Dda University Health Board | W11000025 | LHB | Wales | NaN | NaN | NaN | 1 |
CB20QQ | Addenbrooke's Hospital, Cambridge | AD | Addenbrooke's Hospital | 1 | 1 | 1 | nearest | Cambridge 013D | E01017995 | NHS Cambridgeshire and Peterborough ICB - 06H | E38000260 | SICBL | England | NHS Cambridgeshire and Peterborough Integrated... | E54000056 | East of England (South) | 1 |
L97AL | University Hospital Aintree, Liverpool | AI | University Hospital Aintree | 1 | 1 | 1 | nearest | Liverpool 005A | E01006654 | NHS Cheshire and Merseyside ICB - 99A | E38000101 | SICBL | England | NHS Cheshire and Merseyside Integrated Care Board | E54000008 | Cheshire and Merseyside | 1 |
CH495PE | Arrowe Park Hospital, Wirral | AR | Wirral Arrowe Park Hospital | 1 | 0 | 0 | nearest | Wirral 025B | E01007251 | NHS Cheshire and Merseyside ICB - 12F | E38000208 | SICBL | England | NHS Cheshire and Merseyside Integrated Care Board | E54000008 | Cheshire and Merseyside | 1 |
BA13NG | Royal United Hospital Bath | BA | Royal United Hospital Bath | 1 | 0 | 0 | nearest | Bath and North East Somerset 008B | E01014428 | NHS Bath and North East Somerset, Swindon and ... | E38000231 | SICBL | England | NHS Bath and North East Somerset, Swindon and ... | E54000040 | Gloucester, BSW, BNSSG and Somerset | 1 |
Find LSOA-hospital travel time#
travel_matrix = stroke_maps.load_data.travel_time_matrix_lsoa()
# Show the first five rows and columns:
travel_matrix.iloc[:5, :5]
B152TH | B714HJ | B95SS | BA13NG | BA214AT | |
---|---|---|---|---|---|
LSOA | |||||
Adur 001A | 173.3 | 179.8 | 171.2 | 161.5 | 152.9 |
Adur 001B | 173.3 | 179.8 | 172.3 | 161.5 | 152.9 |
Adur 001C | 173.3 | 180.9 | 172.3 | 150.8 | 151.9 |
Adur 001D | 173.3 | 180.9 | 172.3 | 161.5 | 152.9 |
Adur 001E | 174.4 | 180.9 | 173.3 | 150.8 | 151.9 |
# Limit LSOAs to England if required.
# Only keep LSOAs that are matched to the SICBL region type.
# SICBL are for England and LHB are for Wales.
if limit_to_england:
# Load the LSOA-region lookup data:
df_lsoa_regions = stroke_maps.load_data.lsoa_region_lookup()
df_regions = stroke_maps.load_data.region_lookup()
# Merge the ISDN names into the LSOA-region lookup:
df_lsoa_regions = pd.merge(
df_lsoa_regions.reset_index(),
df_regions.reset_index()[['region_code', 'isdn']],
on='region_code', how='left'
)
# Pick out the names of LSOA contained within SICBL:
england_lsoa = df_lsoa_regions.loc[df_lsoa_regions['region_type'] == 'SICBL', 'lsoa']
# Limit the travel matrix to only those LSOA:
travel_matrix_mask = travel_matrix.index.isin(england_lsoa)
travel_matrix = travel_matrix.loc[travel_matrix_mask].copy()
# Identify closest IVT unit
ivt_hospitals = list(hospitals[hospitals['use_ivt'] == 1].index)
df_catchment_ivt = stroke_maps.catchment.find_nearest_unit(travel_matrix[ivt_hospitals])
df_catchment_ivt.head(3)
unit_travel_time | unit_postcode | |
---|---|---|
LSOA | ||
Adur 001A | 17.6 | BN25BE |
Adur 001B | 18.7 | BN25BE |
Adur 001C | 17.6 | BN112DH |
# Identify closest MT unit
mt_hospitals = list(hospitals[hospitals['use_mt'] == 1].index)
df_catchment_mt = stroke_maps.catchment.find_nearest_unit(travel_matrix[mt_hospitals])
df_catchment_mt.head(3)
unit_travel_time | unit_postcode | |
---|---|---|
LSOA | ||
Adur 001A | 17.6 | BN25BE |
Adur 001B | 18.7 | BN25BE |
Adur 001C | 19.8 | BN25BE |
Find inter-hospital travel time#
df_transfer = stroke_maps.catchment.calculate_transfer_units(hospitals)
df_transfer.head(3)
transfer_unit_travel_time | transfer_unit_postcode | |
---|---|---|
postcode | ||
SY231ER | 135.8 | CF144XW |
CB20QQ | 0.0 | CB20QQ |
L97AL | 0.0 | L97AL |
Gather travel time information#
# Copy over IVT unit info:
df_pathway = df_catchment_ivt.copy()
df_pathway = df_pathway.rename(columns={
'unit_travel_time': 'closest_ivt_time',
'unit_postcode': 'closest_ivt_unit'
})
# Merge in MT unit info:
df_pathway = pd.merge(
df_pathway, df_catchment_mt,
left_index=True, right_index=True, how='left'
)
df_pathway = df_pathway.rename(columns={
'unit_travel_time': 'closest_mt_time',
'unit_postcode': 'closest_mt_unit'
})
# Merge in transfer unit info:
df_pathway = pd.merge(
df_pathway, df_transfer,
left_on='closest_ivt_unit', right_index=True, how='left'
)
df_pathway = df_pathway.rename(columns={
'transfer_unit_travel_time': 'transfer_mt_time',
'transfer_unit_postcode': 'transfer_mt_unit'
})
# Is a transfer required?
df_pathway['mt_transfer_required'] = (
df_pathway['closest_ivt_unit'] != df_pathway['closest_mt_unit'])
Add on stroke pathway timings#
onset_to_ambulance_arrival = 60
arrival_to_ivt = 30
arrival_to_mt = 90
net_operational_delay_to_mt_for_transfer = 60
# Drip-and-ship:
df_pathway['ivt_drip_ship'] = (
onset_to_ambulance_arrival +
df_pathway['closest_ivt_time'] +
arrival_to_ivt
)
df_pathway['mt_drip_ship'] = (
onset_to_ambulance_arrival +
df_pathway['closest_ivt_time'] +
# The times in the following line are only added on if a transfer is required:
((net_operational_delay_to_mt_for_transfer + df_pathway['transfer_mt_time']) * df_pathway['mt_transfer_required']) +
arrival_to_mt
)
# Mothership:
df_pathway['ivt_mothership'] = (
onset_to_ambulance_arrival +
df_pathway['closest_mt_time'] +
arrival_to_ivt
)
df_pathway['mt_mothership'] = (
onset_to_ambulance_arrival +
df_pathway['closest_mt_time'] +
arrival_to_mt
)
# Show df_pathway
df_pathway.head().T
LSOA | Adur 001A | Adur 001B | Adur 001C | Adur 001D | Adur 001E |
---|---|---|---|---|---|
closest_ivt_time | 17.6 | 18.7 | 17.6 | 17.6 | 16.5 |
closest_ivt_unit | BN25BE | BN25BE | BN112DH | BN112DH | BN112DH |
closest_mt_time | 17.6 | 18.7 | 19.8 | 19.8 | 19.8 |
closest_mt_unit | BN25BE | BN25BE | BN25BE | BN25BE | BN25BE |
transfer_mt_time | 0.0 | 0.0 | 31.6 | 31.6 | 31.6 |
transfer_mt_unit | BN25BE | BN25BE | BN25BE | BN25BE | BN25BE |
mt_transfer_required | False | False | True | True | True |
ivt_drip_ship | 107.6 | 108.7 | 107.6 | 107.6 | 106.5 |
mt_drip_ship | 167.6 | 168.7 | 259.2 | 259.2 | 258.1 |
ivt_mothership | 107.6 | 108.7 | 109.8 | 109.8 | 109.8 |
mt_mothership | 167.6 | 168.7 | 169.8 | 169.8 | 169.8 |
Calculate outcomes#
Calculate the proportion mRS<=2 in the no-treatment population.
mrs_dists, mrs_dists_notes = stroke_outcome.outcome_utilities.import_mrs_dists_from_file()
mrs_dists
mRS<=0 | mRS<=1 | mRS<=2 | mRS<=3 | mRS<=4 | mRS<=5 | mRS<=6 | |
---|---|---|---|---|---|---|---|
Stroke type | |||||||
pre_stroke_nlvo | 0.583 | 0.746 | 0.850 | 0.951 | 0.993 | 1.000 | 1 |
pre_stroke_lvo | 0.408 | 0.552 | 0.672 | 0.838 | 0.956 | 1.000 | 1 |
no_treatment_lvo | 0.050 | 0.129 | 0.265 | 0.429 | 0.676 | 0.811 | 1 |
no_treatment_nlvo | 0.198 | 0.460 | 0.580 | 0.708 | 0.856 | 0.918 | 1 |
no_effect_nlvo_ivt_deaths | 0.196 | 0.455 | 0.574 | 0.701 | 0.847 | 0.908 | 1 |
no_effect_lvo_ivt_deaths | 0.048 | 0.124 | 0.255 | 0.414 | 0.653 | 0.783 | 1 |
no_effect_lvo_mt_deaths | 0.048 | 0.124 | 0.255 | 0.412 | 0.649 | 0.779 | 1 |
t0_treatment_nlvo_ivt | 0.445 | 0.642 | 0.752 | 0.862 | 0.941 | 0.967 | 1 |
t0_treatment_lvo_ivt | 0.140 | 0.233 | 0.361 | 0.522 | 0.730 | 0.838 | 1 |
t0_treatment_lvo_mt | 0.306 | 0.429 | 0.548 | 0.707 | 0.851 | 0.915 | 1 |
no_treatment_nlvo_mrsleq2 = mrs_dists.loc['no_treatment_nlvo', 'mRS<=2']
no_treatment_lvo_mrsleq2 = mrs_dists.loc['no_treatment_lvo', 'mRS<=2']
# Set up outcome model
outcome_model = Continuous_outcome()
patient_cohorts = {
'nlvo_ivt': {
'stroke_type_code': 1,
'ivt_chosen_bool': 1,
'mt_chosen_bool': 0,
},
'lvo_ivt': {
'stroke_type_code': 2,
'ivt_chosen_bool': 1,
'mt_chosen_bool': 0,
},
'lvo_ivt_mt': {
'stroke_type_code': 2,
'ivt_chosen_bool': 1,
'mt_chosen_bool': 1,
},
'lvo_mt': {
'stroke_type_code': 2,
'ivt_chosen_bool': 0,
'mt_chosen_bool': 1,
},
}
df_patients = pd.DataFrame()
# Store averaged outcomes in here:
df_results = pd.DataFrame()
# Store mRS distributions in here:
df_mrs = pd.DataFrame()
for model_name in ['drip_ship', 'mothership']:
df_patients['onset_to_needle_mins'] = df_pathway[f'ivt_{model_name}']
df_patients['onset_to_puncture_mins'] = df_pathway[f'mt_{model_name}']
# df_results[f'{model_name}_onset_to_needle_mins'] = df_patients['onset_to_needle_mins'].copy()
# df_results[f'{model_name}_onset_to_puncture_mins'] = df_patients['onset_to_puncture_mins'].copy()
for cohort_name, cohort_dict in patient_cohorts.items():
# Assign patient details:
df_patients['stroke_type_code'] = cohort_dict['stroke_type_code']
df_patients['ivt_chosen_bool'] = cohort_dict['ivt_chosen_bool']
df_patients['mt_chosen_bool'] = cohort_dict['mt_chosen_bool']
# Run outcomes:
outcome_model.assign_patients_to_trial(df_patients)
# Calculate outcomes:
patient_data_dict, outcomes_by_stroke_type, full_cohort_outcomes = (
outcome_model.calculate_outcomes())
# Make a copy of the results:
outcomes_by_stroke_type = copy.copy(outcomes_by_stroke_type)
full_cohort_outcomes = copy.copy(full_cohort_outcomes)
# Place the relevant results into the results dataframe.
# Round them to 5 decimal places which should be plenty.
df_results[f'{model_name}_{cohort_name}_added_utility'] = np.round(
full_cohort_outcomes['each_patient_utility_shift'], 5)
df_results[f'{model_name}_{cohort_name}_mean_mrs'] = np.round(
full_cohort_outcomes['each_patient_mrs_post_stroke'], 5)
df_results[f'{model_name}_{cohort_name}_mrs_less_equal_2'] = np.round(
full_cohort_outcomes['each_patient_mrs_dist_post_stroke'][:, 2], 5)
df_results[f'{model_name}_{cohort_name}_mrs_shift'] = np.round(
full_cohort_outcomes['each_patient_mrs_shift'], 5)
# Calculate the shift in the proportion mRS<=2
# compared with the no-treatment population.
if cohort_dict['stroke_type_code'] == 1:
no_treatment_mrsleq2 = no_treatment_nlvo_mrsleq2
else:
no_treatment_mrsleq2 = no_treatment_lvo_mrsleq2
# Round the results again to avoid floating point errors.
df_results[f'{model_name}_{cohort_name}_added_mrs_less_equal_2'] = (
np.round((
df_results[f'{model_name}_{cohort_name}_mrs_less_equal_2'] -
no_treatment_mrsleq2
), 5))
# Copy over the mRS distributions:
# # One list of mRS values per row (patient) in the data.
outs = full_cohort_outcomes['each_patient_mrs_dist_post_stroke'].copy()
outs = np.round(outs, 5).tolist()
df_mrs[[f'{model_name}_{cohort_name}_mrs_dists_{i}' for i in range(7)]] = outs
Merge the outcome results into the travel time dataframe:
df_results.index = df_pathway.index
df_results = pd.concat((df_pathway, df_results), axis='columns')
df_results.head(5).T
LSOA | Adur 001A | Adur 001B | Adur 001C | Adur 001D | Adur 001E |
---|---|---|---|---|---|
closest_ivt_time | 17.6 | 18.7 | 17.6 | 17.6 | 16.5 |
closest_ivt_unit | BN25BE | BN25BE | BN112DH | BN112DH | BN112DH |
closest_mt_time | 17.6 | 18.7 | 19.8 | 19.8 | 19.8 |
closest_mt_unit | BN25BE | BN25BE | BN25BE | BN25BE | BN25BE |
transfer_mt_time | 0.0 | 0.0 | 31.6 | 31.6 | 31.6 |
transfer_mt_unit | BN25BE | BN25BE | BN25BE | BN25BE | BN25BE |
mt_transfer_required | False | False | True | True | True |
ivt_drip_ship | 107.6 | 108.7 | 107.6 | 107.6 | 106.5 |
mt_drip_ship | 167.6 | 168.7 | 259.2 | 259.2 | 258.1 |
ivt_mothership | 107.6 | 108.7 | 109.8 | 109.8 | 109.8 |
mt_mothership | 167.6 | 168.7 | 169.8 | 169.8 | 169.8 |
drip_ship_nlvo_ivt_added_utility | 0.11685 | 0.11641 | 0.11685 | 0.11685 | 0.1173 |
drip_ship_nlvo_ivt_mean_mrs | 1.63653 | 1.63913 | 1.63653 | 1.63653 | 1.63394 |
drip_ship_nlvo_ivt_mrs_less_equal_2 | 0.70649 | 0.706 | 0.70649 | 0.70649 | 0.70698 |
drip_ship_nlvo_ivt_mrs_shift | -0.64347 | -0.64087 | -0.64347 | -0.64347 | -0.64606 |
drip_ship_nlvo_ivt_added_mrs_less_equal_2 | 0.12649 | 0.126 | 0.12649 | 0.12649 | 0.12698 |
drip_ship_lvo_ivt_added_utility | 0.05872 | 0.05841 | 0.05872 | 0.05872 | 0.05902 |
drip_ship_lvo_ivt_mean_mrs | 3.34655 | 3.34823 | 3.34655 | 3.34655 | 3.34487 |
drip_ship_lvo_ivt_mrs_less_equal_2 | 0.32879 | 0.32847 | 0.32879 | 0.32879 | 0.32911 |
drip_ship_lvo_ivt_mrs_shift | -0.29345 | -0.29177 | -0.29345 | -0.29345 | -0.29513 |
drip_ship_lvo_ivt_added_mrs_less_equal_2 | 0.06379 | 0.06347 | 0.06379 | 0.06379 | 0.06411 |
drip_ship_lvo_ivt_mt_added_utility | 0.16361 | 0.16295 | 0.10928 | 0.10928 | 0.10992 |
drip_ship_lvo_ivt_mt_mean_mrs | 2.81136 | 2.81494 | 3.10174 | 3.10174 | 3.09835 |
drip_ship_lvo_ivt_mt_mrs_less_equal_2 | 0.43807 | 0.43736 | 0.37981 | 0.37981 | 0.38049 |
drip_ship_lvo_ivt_mt_mrs_shift | -0.82864 | -0.82506 | -0.53826 | -0.53826 | -0.54165 |
drip_ship_lvo_ivt_mt_added_mrs_less_equal_2 | 0.17307 | 0.17236 | 0.11481 | 0.11481 | 0.11549 |
drip_ship_lvo_mt_added_utility | 0.16361 | 0.16295 | 0.10928 | 0.10928 | 0.10992 |
drip_ship_lvo_mt_mean_mrs | 2.81136 | 2.81494 | 3.10174 | 3.10174 | 3.09835 |
drip_ship_lvo_mt_mrs_less_equal_2 | 0.43807 | 0.43736 | 0.37981 | 0.37981 | 0.38049 |
drip_ship_lvo_mt_mrs_shift | -0.82864 | -0.82506 | -0.53826 | -0.53826 | -0.54165 |
drip_ship_lvo_mt_added_mrs_less_equal_2 | 0.17307 | 0.17236 | 0.11481 | 0.11481 | 0.11549 |
mothership_nlvo_ivt_added_utility | 0.11685 | 0.11641 | 0.11596 | 0.11596 | 0.11596 |
mothership_nlvo_ivt_mean_mrs | 1.63653 | 1.63913 | 1.64173 | 1.64173 | 1.64173 |
mothership_nlvo_ivt_mrs_less_equal_2 | 0.70649 | 0.706 | 0.70551 | 0.70551 | 0.70551 |
mothership_nlvo_ivt_mrs_shift | -0.64347 | -0.64087 | -0.63827 | -0.63827 | -0.63827 |
mothership_nlvo_ivt_added_mrs_less_equal_2 | 0.12649 | 0.126 | 0.12551 | 0.12551 | 0.12551 |
mothership_lvo_ivt_added_utility | 0.05872 | 0.05841 | 0.05811 | 0.05811 | 0.05811 |
mothership_lvo_ivt_mean_mrs | 3.34655 | 3.34823 | 3.3499 | 3.3499 | 3.3499 |
mothership_lvo_ivt_mrs_less_equal_2 | 0.32879 | 0.32847 | 0.32815 | 0.32815 | 0.32815 |
mothership_lvo_ivt_mrs_shift | -0.29345 | -0.29177 | -0.2901 | -0.2901 | -0.2901 |
mothership_lvo_ivt_added_mrs_less_equal_2 | 0.06379 | 0.06347 | 0.06315 | 0.06315 | 0.06315 |
mothership_lvo_ivt_mt_added_utility | 0.16361 | 0.16295 | 0.16229 | 0.16229 | 0.16229 |
mothership_lvo_ivt_mt_mean_mrs | 2.81136 | 2.81494 | 2.81852 | 2.81852 | 2.81852 |
mothership_lvo_ivt_mt_mrs_less_equal_2 | 0.43807 | 0.43736 | 0.43664 | 0.43664 | 0.43664 |
mothership_lvo_ivt_mt_mrs_shift | -0.82864 | -0.82506 | -0.82148 | -0.82148 | -0.82148 |
mothership_lvo_ivt_mt_added_mrs_less_equal_2 | 0.17307 | 0.17236 | 0.17164 | 0.17164 | 0.17164 |
mothership_lvo_mt_added_utility | 0.16361 | 0.16295 | 0.16229 | 0.16229 | 0.16229 |
mothership_lvo_mt_mean_mrs | 2.81136 | 2.81494 | 2.81852 | 2.81852 | 2.81852 |
mothership_lvo_mt_mrs_less_equal_2 | 0.43807 | 0.43736 | 0.43664 | 0.43664 | 0.43664 |
mothership_lvo_mt_mrs_shift | -0.82864 | -0.82506 | -0.82148 | -0.82148 | -0.82148 |
mothership_lvo_mt_added_mrs_less_equal_2 | 0.17307 | 0.17236 | 0.17164 | 0.17164 | 0.17164 |
df_mrs.index = df_pathway.index
df_mrs = pd.concat((df_pathway, df_mrs), axis='columns')
df_mrs.head(5).T
LSOA | Adur 001A | Adur 001B | Adur 001C | Adur 001D | Adur 001E |
---|---|---|---|---|---|
closest_ivt_time | 17.6 | 18.7 | 17.6 | 17.6 | 16.5 |
closest_ivt_unit | BN25BE | BN25BE | BN112DH | BN112DH | BN112DH |
closest_mt_time | 17.6 | 18.7 | 19.8 | 19.8 | 19.8 |
closest_mt_unit | BN25BE | BN25BE | BN25BE | BN25BE | BN25BE |
transfer_mt_time | 0.0 | 0.0 | 31.6 | 31.6 | 31.6 |
transfer_mt_unit | BN25BE | BN25BE | BN25BE | BN25BE | BN25BE |
mt_transfer_required | False | False | True | True | True |
ivt_drip_ship | 107.6 | 108.7 | 107.6 | 107.6 | 106.5 |
mt_drip_ship | 167.6 | 168.7 | 259.2 | 259.2 | 258.1 |
ivt_mothership | 107.6 | 108.7 | 109.8 | 109.8 | 109.8 |
mt_mothership | 167.6 | 168.7 | 169.8 | 169.8 | 169.8 |
drip_ship_nlvo_ivt_mrs_dists_0 | 0.36359 | 0.36279 | 0.36359 | 0.36359 | 0.3644 |
drip_ship_nlvo_ivt_mrs_dists_1 | 0.59059 | 0.59006 | 0.59059 | 0.59059 | 0.59113 |
drip_ship_nlvo_ivt_mrs_dists_2 | 0.70649 | 0.706 | 0.70649 | 0.70649 | 0.70698 |
drip_ship_nlvo_ivt_mrs_dists_3 | 0.82535 | 0.82494 | 0.82535 | 0.82535 | 0.82577 |
drip_ship_nlvo_ivt_mrs_dists_4 | 0.92188 | 0.92166 | 0.92188 | 0.92188 | 0.9221 |
drip_ship_nlvo_ivt_mrs_dists_5 | 0.95555 | 0.95542 | 0.95555 | 0.95555 | 0.95568 |
drip_ship_nlvo_ivt_mrs_dists_6 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 |
drip_ship_lvo_ivt_mrs_dists_0 | 0.10443 | 0.10411 | 0.10443 | 0.10443 | 0.10475 |
drip_ship_lvo_ivt_mrs_dists_1 | 0.19642 | 0.19607 | 0.19642 | 0.19642 | 0.19677 |
drip_ship_lvo_ivt_mrs_dists_2 | 0.32879 | 0.32847 | 0.32879 | 0.32879 | 0.32911 |
drip_ship_lvo_ivt_mrs_dists_3 | 0.49102 | 0.49071 | 0.49102 | 0.49102 | 0.49134 |
drip_ship_lvo_ivt_mrs_dists_4 | 0.70919 | 0.70898 | 0.70919 | 0.70919 | 0.70941 |
drip_ship_lvo_ivt_mrs_dists_5 | 0.82359 | 0.82344 | 0.82359 | 0.82359 | 0.82375 |
drip_ship_lvo_ivt_mrs_dists_6 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 |
drip_ship_lvo_ivt_mt_mrs_dists_0 | 0.17136 | 0.17065 | 0.12027 | 0.12027 | 0.1208 |
drip_ship_lvo_ivt_mt_mrs_dists_1 | 0.29552 | 0.29472 | 0.23375 | 0.23375 | 0.23443 |
drip_ship_lvo_ivt_mt_mrs_dists_2 | 0.43807 | 0.43736 | 0.37981 | 0.37981 | 0.38049 |
drip_ship_lvo_ivt_mt_mrs_dists_3 | 0.61042 | 0.60975 | 0.55308 | 0.55308 | 0.55378 |
drip_ship_lvo_ivt_mt_mrs_dists_4 | 0.79391 | 0.79349 | 0.75647 | 0.75647 | 0.75695 |
drip_ship_lvo_ivt_mt_mrs_dists_5 | 0.87937 | 0.8791 | 0.85488 | 0.85488 | 0.8552 |
drip_ship_lvo_ivt_mt_mrs_dists_6 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 |
drip_ship_lvo_mt_mrs_dists_0 | 0.17136 | 0.17065 | 0.12027 | 0.12027 | 0.1208 |
drip_ship_lvo_mt_mrs_dists_1 | 0.29552 | 0.29472 | 0.23375 | 0.23375 | 0.23443 |
drip_ship_lvo_mt_mrs_dists_2 | 0.43807 | 0.43736 | 0.37981 | 0.37981 | 0.38049 |
drip_ship_lvo_mt_mrs_dists_3 | 0.61042 | 0.60975 | 0.55308 | 0.55308 | 0.55378 |
drip_ship_lvo_mt_mrs_dists_4 | 0.79391 | 0.79349 | 0.75647 | 0.75647 | 0.75695 |
drip_ship_lvo_mt_mrs_dists_5 | 0.87937 | 0.8791 | 0.85488 | 0.85488 | 0.8552 |
drip_ship_lvo_mt_mrs_dists_6 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 |
mothership_nlvo_ivt_mrs_dists_0 | 0.36359 | 0.36279 | 0.36199 | 0.36199 | 0.36199 |
mothership_nlvo_ivt_mrs_dists_1 | 0.59059 | 0.59006 | 0.58952 | 0.58952 | 0.58952 |
mothership_nlvo_ivt_mrs_dists_2 | 0.70649 | 0.706 | 0.70551 | 0.70551 | 0.70551 |
mothership_nlvo_ivt_mrs_dists_3 | 0.82535 | 0.82494 | 0.82453 | 0.82453 | 0.82453 |
mothership_nlvo_ivt_mrs_dists_4 | 0.92188 | 0.92166 | 0.92144 | 0.92144 | 0.92144 |
mothership_nlvo_ivt_mrs_dists_5 | 0.95555 | 0.95542 | 0.95528 | 0.95528 | 0.95528 |
mothership_nlvo_ivt_mrs_dists_6 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 |
mothership_lvo_ivt_mrs_dists_0 | 0.10443 | 0.10411 | 0.1038 | 0.1038 | 0.1038 |
mothership_lvo_ivt_mrs_dists_1 | 0.19642 | 0.19607 | 0.19572 | 0.19572 | 0.19572 |
mothership_lvo_ivt_mrs_dists_2 | 0.32879 | 0.32847 | 0.32815 | 0.32815 | 0.32815 |
mothership_lvo_ivt_mrs_dists_3 | 0.49102 | 0.49071 | 0.49039 | 0.49039 | 0.49039 |
mothership_lvo_ivt_mrs_dists_4 | 0.70919 | 0.70898 | 0.70876 | 0.70876 | 0.70876 |
mothership_lvo_ivt_mrs_dists_5 | 0.82359 | 0.82344 | 0.82329 | 0.82329 | 0.82329 |
mothership_lvo_ivt_mrs_dists_6 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 |
mothership_lvo_ivt_mt_mrs_dists_0 | 0.17136 | 0.17065 | 0.16995 | 0.16995 | 0.16995 |
mothership_lvo_ivt_mt_mrs_dists_1 | 0.29552 | 0.29472 | 0.29393 | 0.29393 | 0.29393 |
mothership_lvo_ivt_mt_mrs_dists_2 | 0.43807 | 0.43736 | 0.43664 | 0.43664 | 0.43664 |
mothership_lvo_ivt_mt_mrs_dists_3 | 0.61042 | 0.60975 | 0.60907 | 0.60907 | 0.60907 |
mothership_lvo_ivt_mt_mrs_dists_4 | 0.79391 | 0.79349 | 0.79306 | 0.79306 | 0.79306 |
mothership_lvo_ivt_mt_mrs_dists_5 | 0.87937 | 0.8791 | 0.87882 | 0.87882 | 0.87882 |
mothership_lvo_ivt_mt_mrs_dists_6 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 |
mothership_lvo_mt_mrs_dists_0 | 0.17136 | 0.17065 | 0.16995 | 0.16995 | 0.16995 |
mothership_lvo_mt_mrs_dists_1 | 0.29552 | 0.29472 | 0.29393 | 0.29393 | 0.29393 |
mothership_lvo_mt_mrs_dists_2 | 0.43807 | 0.43736 | 0.43664 | 0.43664 | 0.43664 |
mothership_lvo_mt_mrs_dists_3 | 0.61042 | 0.60975 | 0.60907 | 0.60907 | 0.60907 |
mothership_lvo_mt_mrs_dists_4 | 0.79391 | 0.79349 | 0.79306 | 0.79306 | 0.79306 |
mothership_lvo_mt_mrs_dists_5 | 0.87937 | 0.8791 | 0.87882 | 0.87882 | 0.87882 |
mothership_lvo_mt_mrs_dists_6 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 |
Save results to file#
df_results.to_csv(os.path.join(dir_output, 'cohort_outcomes.csv'))
df_mrs.to_csv(os.path.join(dir_output, 'cohort_mrs_dists.csv'))
Calculate summary stats for the outcomes:
summary = np.round(df_results.mean(axis=0).T, 5)
summary.to_csv(os.path.join(dir_output, 'cohort_outcomes_summary.csv'), index_label='lsoa')
summary
closest_ivt_time 19.54818
closest_mt_time 34.93931
transfer_mt_time 27.50945
mt_transfer_required 0.67510
ivt_drip_ship 109.54818
mt_drip_ship 237.56350
ivt_mothership 124.93931
mt_mothership 184.93931
drip_ship_nlvo_ivt_added_utility 0.11605
drip_ship_nlvo_ivt_mean_mrs 1.64118
drip_ship_nlvo_ivt_mrs_less_equal_2 0.70561
drip_ship_nlvo_ivt_mrs_shift -0.63882
drip_ship_nlvo_ivt_added_mrs_less_equal_2 0.12561
drip_ship_lvo_ivt_added_utility 0.05818
drip_ship_lvo_ivt_mean_mrs 3.34948
drip_ship_lvo_ivt_mrs_less_equal_2 0.32822
drip_ship_lvo_ivt_mrs_shift -0.29052
drip_ship_lvo_ivt_added_mrs_less_equal_2 0.06322
drip_ship_lvo_ivt_mt_added_utility 0.12224
drip_ship_lvo_ivt_mt_mean_mrs 3.03180
drip_ship_lvo_ivt_mt_mrs_less_equal_2 0.39381
drip_ship_lvo_ivt_mt_mrs_shift -0.60820
drip_ship_lvo_ivt_mt_added_mrs_less_equal_2 0.12881
drip_ship_lvo_mt_added_utility 0.12223
drip_ship_lvo_mt_mean_mrs 3.03199
drip_ship_lvo_mt_mrs_less_equal_2 0.39379
drip_ship_lvo_mt_mrs_shift -0.60801
drip_ship_lvo_mt_added_mrs_less_equal_2 0.12879
mothership_nlvo_ivt_added_utility 0.10969
mothership_nlvo_ivt_mean_mrs 1.67795
mothership_nlvo_ivt_mrs_less_equal_2 0.69864
mothership_nlvo_ivt_mrs_shift -0.60205
mothership_nlvo_ivt_added_mrs_less_equal_2 0.11864
mothership_lvo_ivt_added_utility 0.05395
mothership_lvo_ivt_mean_mrs 3.37261
mothership_lvo_ivt_mrs_less_equal_2 0.32377
mothership_lvo_ivt_mrs_shift -0.26739
mothership_lvo_ivt_added_mrs_less_equal_2 0.05877
mothership_lvo_ivt_mt_added_utility 0.15326
mothership_lvo_ivt_mt_mean_mrs 2.86715
mothership_lvo_ivt_mt_mrs_less_equal_2 0.42692
mothership_lvo_ivt_mt_mrs_shift -0.77285
mothership_lvo_ivt_mt_added_mrs_less_equal_2 0.16192
mothership_lvo_mt_added_utility 0.15326
mothership_lvo_mt_mean_mrs 2.86715
mothership_lvo_mt_mrs_less_equal_2 0.42692
mothership_lvo_mt_mrs_shift -0.77285
mothership_lvo_mt_added_mrs_less_equal_2 0.16192
dtype: float64
Conclusion#
We have calculated all of the outcome data for the separate cohorts and for both the drip-and-ship and mothership scenarios.
The next notebooks combine the cohorts to find the average results for a mixed population.