Descriptive analysis of stroke pathway data#

Aim#

Describe key pathway statistics

  • Restrict data to stroke teams with at least 300 admissions (over three years) and 10 patients receiving thrombolysis.

  • Analyse pathway statistics by stroke team, and combined across all stroke teams.

  • Repeat team and combined analysis by age category (under aged 80 years, and aged 80+).

  • Create histograms of variation in key statistics across stroke teams.

  • Analyse onset-to-arrival (and breakdown by mild and non-mild stroke)

Import libraries and data#

Data has been restricted to stroke teams with at least 300 admissions, with at least 10 patients receiving thrombolysis, over three years.

# import libraries
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

# import data
raw_data = pd.read_csv(
    './../data/2019-11-04-HQIP303-Exeter_MA.csv', low_memory=False)
headings = list(raw_data)
print (headings)
['StrokeTeam', 'PatientUID', 'Pathway', 'S1AgeOnArrival', 'MoreEqual80y', 'S1Gender', 'S1Ethnicity', 'S1OnsetInHospital', 'S1OnsetToArrival_min', 'S1OnsetDateType', 'S1OnsetTimeType', 'S1ArriveByAmbulance', 'S1AdmissionHour', 'S1AdmissionDay', 'S1AdmissionQuarter', 'S1AdmissionYear', 'CongestiveHeartFailure', 'Hypertension', 'AtrialFibrillation', 'Diabetes', 'StrokeTIA', 'AFAntiplatelet', 'AFAnticoagulent', 'AFAnticoagulentVitK', 'AFAnticoagulentDOAC', 'AFAnticoagulentHeparin', 'S2INR', 'S2INRHigh', 'S2INRNK', 'S2NewAFDiagnosis', 'S2RankinBeforeStroke', 'Loc', 'LocQuestions', 'LocCommands', 'BestGaze', 'Visual', 'FacialPalsy', 'MotorArmLeft', 'MotorArmRight', 'MotorLegLeft', 'MotorLegRight', 'LimbAtaxia', 'Sensory', 'BestLanguage', 'Dysarthria', 'ExtinctionInattention', 'S2NihssArrival', 'S2BrainImagingTime_min', 'S2StrokeType', 'S2Thrombolysis', 'Haemorrhagic', 'TimeWindow', 'Comorbidity', 'Medication', 'Refusal', 'Age', 'Improving', 'TooMildSevere', 'TimeUnknownWakeUp', 'OtherMedical', 'S2ThrombolysisTime_min', 'S2TIAInLastMonth']

Show data types

raw_data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 246676 entries, 0 to 246675
Data columns (total 62 columns):
 #   Column                  Non-Null Count   Dtype  
---  ------                  --------------   -----  
 0   StrokeTeam              246676 non-null  object 
 1   PatientUID              246676 non-null  object 
 2   Pathway                 246676 non-null  int64  
 3   S1AgeOnArrival          246676 non-null  object 
 4   MoreEqual80y            246676 non-null  object 
 5   S1Gender                246676 non-null  object 
 6   S1Ethnicity             246676 non-null  object 
 7   S1OnsetInHospital       246676 non-null  object 
 8   S1OnsetToArrival_min    154640 non-null  float64
 9   S1OnsetDateType         246676 non-null  object 
 10  S1OnsetTimeType         246676 non-null  object 
 11  S1ArriveByAmbulance     232503 non-null  object 
 12  S1AdmissionHour         246676 non-null  object 
 13  S1AdmissionDay          246676 non-null  object 
 14  S1AdmissionQuarter      246676 non-null  object 
 15  S1AdmissionYear         246676 non-null  int64  
 16  CongestiveHeartFailure  246676 non-null  object 
 17  Hypertension            246676 non-null  object 
 18  AtrialFibrillation      246676 non-null  object 
 19  Diabetes                246676 non-null  object 
 20  StrokeTIA               246676 non-null  object 
 21  AFAntiplatelet          47691 non-null   object 
 22  AFAnticoagulent         120409 non-null  object 
 23  AFAnticoagulentVitK     93603 non-null   object 
 24  AFAnticoagulentDOAC     93603 non-null   object 
 25  AFAnticoagulentHeparin  93603 non-null   object 
 26  S2INR                   4240 non-null    float64
 27  S2INRHigh               93603 non-null   object 
 28  S2INRNK                 93603 non-null   object 
 29  S2NewAFDiagnosis        70588 non-null   object 
 30  S2RankinBeforeStroke    246676 non-null  int64  
 31  Loc                     246676 non-null  int64  
 32  LocQuestions            236305 non-null  float64
 33  LocCommands             236579 non-null  float64
 34  BestGaze                235003 non-null  float64
 35  Visual                  233231 non-null  float64
 36  FacialPalsy             236381 non-null  float64
 37  MotorArmLeft            236475 non-null  float64
 38  MotorArmRight           236478 non-null  float64
 39  MotorLegLeft            236205 non-null  float64
 40  MotorLegRight           236202 non-null  float64
 41  LimbAtaxia              232480 non-null  float64
 42  Sensory                 233464 non-null  float64
 43  BestLanguage            236047 non-null  float64
 44  Dysarthria              235035 non-null  float64
 45  ExtinctionInattention   234707 non-null  float64
 46  S2NihssArrival          228279 non-null  float64
 47  S2BrainImagingTime_min  245535 non-null  float64
 48  S2StrokeType            245535 non-null  object 
 49  S2Thrombolysis          246676 non-null  object 
 50  Haemorrhagic            215844 non-null  object 
 51  TimeWindow              215844 non-null  object 
 52  Comorbidity             215844 non-null  object 
 53  Medication              215844 non-null  object 
 54  Refusal                 215844 non-null  object 
 55  Age                     215844 non-null  object 
 56  Improving               215844 non-null  object 
 57  TooMildSevere           215844 non-null  object 
 58  TimeUnknownWakeUp       215844 non-null  object 
 59  OtherMedical            215844 non-null  object 
 60  S2ThrombolysisTime_min  28482 non-null   float64
 61  S2TIAInLastMonth        21151 non-null   object 
dtypes: float64(19), int64(4), object(39)
memory usage: 116.7+ MB

Average yearly admissions#

int(raw_data.shape[0]/3)
82225

Restrict original data to hospitals with at least 300 admissions + 10 thrombolysis patients#

keep = []

groups = raw_data.groupby('StrokeTeam') # creates a new object of groups of data

for index, group_df in groups: # each group has an index and a dataframe of data
    
    # Skip if total admissions less than 300 or total thrombolysis < 10
    admissions = group_df.shape[0]
    thrombolysis_received = group_df['S2Thrombolysis'] == 'Yes' 
    if (admissions < 300) or (thrombolysis_received.sum() < 10):
        continue
    
    else: 
        keep.append(group_df)

# Concatenate output
data = pd.DataFrame()
data = pd.concat(keep)

print (data.shape)
(239505, 62)

Stroke types#

data['S2StrokeType'].value_counts()/data['S2StrokeType'].shape[0]
Infarction                           0.873435
Primary Intracerebral Haemorrhage    0.122106
Name: S2StrokeType, dtype: float64

Compare thrombolysis use for out-of-hospital and in-hospital stroke onset#

# Create boolean feature for use of thrombolysis
data['use_thrombolysis'] = data['S2Thrombolysis'] == 'Yes'

# Show percentage of strokes have in hospital onset
in_hospital_onset = data['S1OnsetInHospital'] == 'Yes'
percent_in_hosp = in_hospital_onset.mean() * 100
print (
    f'Percentage of stroke with in-hospital onset: {percent_in_hosp:0.1f}')

# In hospital onset
mask = data['S1OnsetInHospital'] == 'Yes'
thrombolysis_in = data[mask]['use_thrombolysis'].mean() * 100
print (
    f'Thrombolysis use (%) for in-hospital-onset {thrombolysis_in:0.1f}')

# Out of hospital onset
mask = data['S1OnsetInHospital'] == 'No'
thrombolysis_out = data[mask]['use_thrombolysis'].mean() * 100
print (
    f'Thrombolysis use (%) for out-of-hospital-onset {thrombolysis_out:0.1f}')
Percentage of stroke with in-hospital onset: 5.3
Thrombolysis use (%) for in-hospital-onset 12.3
Thrombolysis use (%) for out-of-hospital-onset 11.8

Restrict data to out-of-hospital onset#

mask = data['S1OnsetInHospital'] == 'No'
data = data[mask]

Function for analysis by stroke team#

def analyse_by_team(input_data):
    
    # Copy data
    data = input_data.copy()
    
    # Set up results lists
    stroke_team = []
    admissions = []
    age_80_plus = []
    
    onset_known = []
    rankin_before_stroke_all = []
    nihss_arrival_all = []
    known_arrival_within_4hrs = []
    rankin_before_stroke_4hrs = []
    nihss_arrival_4hrs = []
    onset_arrival_mins_mu = []
    onset_arrival_mins_sigma = []
    scan_within_4_hrs = []
    arrival_scan_mins_mu = []
    arrival_scan_mins_sigma = []
    scan_needle_mins_mu = []
    scan_needle_mins_sigma = []
    arrival_needle_mins_mu = []
    arrival_needle_mins_sigma = []
    onset_needle_mins_mu = []
    onset_needle_mins_sigma = []
    thrombolysis_rate = []
    thrombolysis_after_180_min = []
    thrombolysis_after_270_min = []
    eligible = []
    
    # Split data by stroke team
    groups = data.groupby('StrokeTeam') # creates a new object of groups of data
    group_count = 0
    for index, group_df in groups: 
        group_count += 1
        
        # Record stroke team
        stroke_team.append(index)

        # Record admission numbers
        admissions.append(group_df.shape[0])

        # Get thrombolysis rate
        thrombolysed = group_df['S2Thrombolysis'] == 'Yes'
        thrombolysis_rate.append(thrombolysed.mean())
        
        # Get Rankin before stroke and NIHSS on arrival
        rankin_before_stroke_all.append(group_df['S2RankinBeforeStroke'].mean())
        nihss_arrival_all.append(group_df['S2NihssArrival'].mean())
        
        # Record onset known proportion and remove rest
        f = lambda x: x in ['Precise', 'Best estimate']
        mask = group_df['S1OnsetTimeType'].apply(f)
        onset_known.append(mask.mean())
        group_df = group_df[mask]

        # Record onset <4 hours and remove rest
        mask = group_df['S1OnsetToArrival_min'] <= 240
        known_arrival_within_4hrs.append(mask.mean())
        group_df = group_df[mask]
        
        # Get Rankin before stroke and NIHSS on arrival
        rankin_before_stroke_4hrs.append(
            group_df['S2RankinBeforeStroke'].mean())
        nihss_arrival_4hrs.append(group_df['S2NihssArrival'].mean())

        # Calc proportion 80+ (of those arriving within 4 hours)
        age_filter = group_df['MoreEqual80y'] == 'Yes'
        age_80_plus.append(age_filter.mean())

        # Get onset to arrival (of those arriving within 4 hours)
        onset_to_arrival = group_df['S1OnsetToArrival_min']
        onset_arrival_mins_mu.append(onset_to_arrival.mean())
        onset_arrival_mins_sigma.append(onset_to_arrival.std())

        # Record scan within 4 hours of arrival (and remove the rest)
        mask = group_df['S2BrainImagingTime_min'] <= 240
        scan_within_4_hrs.append(mask.mean())
        group_df = group_df[mask]

        # Record arrival to scan (of those arriving within 4 hours)
        arrival_to_scan = group_df['S2BrainImagingTime_min']
        arrival_scan_mins_mu.append(arrival_to_scan.mean())
        arrival_scan_mins_sigma.append(arrival_to_scan.std())

        # Thrombolysis given (of those scanned within 4 hours of arrival)
        thrombolysed_mask = group_df['S2Thrombolysis'] == 'Yes'
        eligible.append(thrombolysed_mask.mean())

        # Scan to needle
        thrombolysed = group_df[thrombolysed_mask]
        scan_to_needle = (thrombolysed['S2ThrombolysisTime_min'] - 
                          thrombolysed['S2BrainImagingTime_min'])
        scan_needle_mins_mu.append(scan_to_needle.mean())
        scan_needle_mins_sigma.append(scan_to_needle.std())
        
        # Arrival to needle
        arrival_needle_mins_mu.append(
            thrombolysed['S2ThrombolysisTime_min'].mean())
        arrival_needle_mins_sigma.append(
            thrombolysed['S2ThrombolysisTime_min'].std())
        
        # Onset to needle
        onset_to_needle = (thrombolysed['S1OnsetToArrival_min'] + 
                          thrombolysed['S2ThrombolysisTime_min'])
        onset_needle_mins_mu.append(onset_to_needle.mean())
        onset_needle_mins_sigma.append(onset_to_needle.std())
        
        # Proportions of thrombolysis after 180 or 270 min
        thrombolysis_after_180 = onset_to_needle > 180
        thrombolysis_after_270 = onset_to_needle > 270
        thrombolysis_after_180_min.append(thrombolysis_after_180.mean())
        thrombolysis_after_270_min.append(thrombolysis_after_270.mean())
        
    df = pd.DataFrame()
    df['stroke_team'] = stroke_team
    df['thrombolysis_rate'] = thrombolysis_rate
    df['arrivals'] = admissions
    df['80_plus'] = age_80_plus
    df['rankin_before_stroke_all'] = rankin_before_stroke_all
    df['nihss_arrival_all'] = nihss_arrival_all
    df['onset_known'] = onset_known
    df['known_arrival_within_4hrs'] = known_arrival_within_4hrs
    df['known_arrival_within_4hrs_all'] = \
        df['onset_known'] * df['known_arrival_within_4hrs']
    df['rankin_before_stroke_4hrs'] = rankin_before_stroke_4hrs
    df['nihss_arrival_4hrs'] = nihss_arrival_4hrs
    df['onset_arrival_mins_mu'] = onset_arrival_mins_mu
    df['onset_arrival_mins_sigma'] = onset_arrival_mins_sigma
    df['scan_within_4_hrs'] = scan_within_4_hrs
    df['arrival_scan_mins_mu'] = arrival_scan_mins_mu
    df['arrival_scan_mins_sigma'] = arrival_scan_mins_sigma
    df['eligable'] = eligible
    df['scan_needle_mins_mu'] = scan_needle_mins_mu
    df['scan_needle_mins_sigma'] = scan_needle_mins_sigma
    df['arrival_needle_mins_mu'] = arrival_needle_mins_mu
    df['arrival_needle_mins_sigma'] = arrival_needle_mins_sigma
    df['onset_needle_mins_mu'] = onset_needle_mins_mu
    df['onset_needle_mins_sigma'] = onset_needle_mins_sigma   
    df['thrombolysis_after_180_min'] = thrombolysis_after_180_min
    df['thrombolysis_after_270_min'] = thrombolysis_after_270_min
    
    return df

Create analysis by team and show summary#

analysis_by_team = analyse_by_team(data)
analysis_by_team.to_csv('output/full_analysis_by_team.csv')
summary_by_hospital = analysis_by_team.describe().T
summary_by_hospital
count mean std min 25% 50% 75% max
thrombolysis_rate 132.0 0.114536 0.035449 0.015306 0.093239 0.109547 0.133314 0.243174
arrivals 132.0 1718.333333 832.249409 303.000000 1133.000000 1632.500000 2265.250000 6118.000000
80_plus 132.0 0.425635 0.056416 0.292308 0.387089 0.427573 0.457896 0.576220
rankin_before_stroke_all 132.0 1.040435 0.258761 0.512531 0.843626 1.032913 1.202876 1.860384
nihss_arrival_all 132.0 7.393900 0.948271 4.543634 6.698829 7.404792 8.067855 10.277926
onset_known 132.0 0.665679 0.134064 0.344784 0.573593 0.641978 0.752881 0.988275
known_arrival_within_4hrs 132.0 0.600743 0.089733 0.257034 0.557876 0.608542 0.662325 0.813584
known_arrival_within_4hrs_all 132.0 0.392147 0.062162 0.222646 0.352730 0.392458 0.430548 0.558317
rankin_before_stroke_4hrs 132.0 1.052002 0.264767 0.455108 0.877631 1.059910 1.204151 1.843863
nihss_arrival_4hrs 132.0 9.119220 1.107748 6.108696 8.419594 9.168358 9.916195 11.728546
onset_arrival_mins_mu 132.0 110.604942 6.663145 90.306383 106.872313 110.812667 115.087515 132.572368
onset_arrival_mins_sigma 132.0 52.401532 2.342917 46.456599 50.822598 52.119960 53.668951 63.899224
scan_within_4_hrs 132.0 0.947503 0.030163 0.847328 0.932828 0.953808 0.969191 1.000000
arrival_scan_mins_mu 132.0 42.991449 11.548507 18.635392 35.619539 42.907270 50.628576 92.923345
arrival_scan_mins_sigma 132.0 43.168750 6.917284 24.002919 38.927934 42.655178 47.546395 64.428643
eligable 132.0 0.301030 0.078284 0.073171 0.248810 0.293434 0.359811 0.497462
scan_needle_mins_mu 132.0 39.683068 12.020205 19.086768 30.691358 37.401892 45.949020 92.147059
scan_needle_mins_sigma 132.0 26.538991 8.507326 7.940403 21.293485 25.088262 29.942953 65.858529
arrival_needle_mins_mu 132.0 63.474563 15.121720 26.472222 54.488376 60.043478 71.720339 111.441558
arrival_needle_mins_sigma 132.0 32.814839 8.395361 8.195769 27.883198 32.228478 36.453541 69.820865
onset_needle_mins_mu 132.0 158.393399 13.147797 127.000000 149.722619 156.531821 166.692531 189.662338
onset_needle_mins_sigma 132.0 52.274870 5.907052 39.071523 48.582379 51.275398 54.895491 83.336167
thrombolysis_after_180_min 132.0 0.309629 0.093026 0.080000 0.250245 0.289664 0.356365 0.588235
thrombolysis_after_270_min 132.0 0.017742 0.015162 0.000000 0.008063 0.014728 0.025703 0.069853
# Save summary to csv
summary_by_hospital.to_csv('output/pathway_summary_by_hopsital.csv')

Analyse for all patients together#

# Set all StrokeTeam to same
single_group = data.copy()
single_group['StrokeTeam'] = "na"
analysis_all = analyse_by_team(single_group).T

# Add means to new DataFrame
stats_by_age = pd.DataFrame()
stats_by_age['all'] = analysis_all[0]
analysis_all.to_csv('output/pathway_summary_all.csv')

Analysis by under age 80 vs 80+#

Repeat general and hospital level analysis by age stratification

# Mask for under 80
mask = data['MoreEqual80y'] == 'No'
data_under_80 = data[mask]
# Mask for 80 plus
mask = data['MoreEqual80y'] == 'Yes'
data_80_plus = data[mask]

Under age 80#

analysis_by_team_under_80 = analyse_by_team(data_under_80)
summary_by_hospital_under_80 = analysis_by_team_under_80.describe().T
summary_by_hospital_under_80
count mean std min 25% 50% 75% max
thrombolysis_rate 132.0 0.127182 0.038002 0.013064 0.104283 0.123472 0.150482 0.262436
arrivals 132.0 1003.037879 529.410379 173.000000 636.000000 941.500000 1286.500000 3999.000000
80_plus 132.0 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
rankin_before_stroke_all 132.0 0.642800 0.204014 0.221030 0.493693 0.609459 0.758040 1.420674
nihss_arrival_all 132.0 6.286699 0.856764 3.749164 5.766698 6.342502 6.799700 9.328110
onset_known 132.0 0.679982 0.130020 0.377171 0.588716 0.660804 0.760079 0.985591
known_arrival_within_4hrs 132.0 0.584347 0.090390 0.222084 0.537210 0.594057 0.649928 0.807645
known_arrival_within_4hrs_all 132.0 0.389793 0.060399 0.212589 0.351842 0.391457 0.423625 0.544338
rankin_before_stroke_4hrs 132.0 0.617723 0.214004 0.148148 0.462979 0.597158 0.752650 1.443884
nihss_arrival_4hrs 132.0 8.085814 1.080190 5.147959 7.459996 8.037950 8.714991 11.512821
onset_arrival_mins_mu 132.0 108.278108 6.901565 91.458333 103.999891 107.773886 113.655551 127.885057
onset_arrival_mins_sigma 132.0 52.352397 2.714954 46.708726 50.718741 52.128487 53.906830 61.943113
scan_within_4_hrs 132.0 0.949423 0.031731 0.833333 0.933499 0.958696 0.969423 1.000000
arrival_scan_mins_mu 132.0 42.717327 11.121473 18.496907 36.361292 42.133225 50.423320 94.846667
arrival_scan_mins_sigma 132.0 43.169589 7.199394 26.084190 38.407673 43.699258 47.659708 66.206585
eligable 132.0 0.334699 0.083152 0.073333 0.279830 0.333333 0.391261 0.524590
scan_needle_mins_mu 132.0 40.224581 12.107333 18.303333 32.081609 38.742367 46.597925 93.260870
scan_needle_mins_sigma 132.0 27.284895 10.235558 8.453550 21.021526 25.689491 28.915382 78.491646
arrival_needle_mins_mu 132.0 64.712453 15.445930 26.375000 54.799590 62.553309 73.987337 109.178571
arrival_needle_mins_sigma 132.0 34.256721 10.043992 8.365604 28.970198 32.771987 37.719027 83.959546
onset_needle_mins_mu 132.0 159.157281 13.620341 120.600000 149.626050 157.045433 168.504335 191.566667
onset_needle_mins_sigma 132.0 53.566155 7.108638 38.454895 49.181509 52.290158 56.504757 86.605961
thrombolysis_after_180_min 132.0 0.316502 0.094463 0.000000 0.252605 0.301239 0.375613 0.565217
thrombolysis_after_270_min 132.0 0.019459 0.018550 0.000000 0.007233 0.015268 0.028169 0.095238
summary_by_hospital_under_80.to_csv('output/pathway_summary_by_hopsital_under_80.csv')
 # Set all StrokeTeam to same
single_group = data_under_80.copy()
single_group['StrokeTeam'] = "na"
analysis_all = analyse_by_team(single_group).T
stats_by_age['under_80'] = analysis_all[0]

Aged 80+#

analysis_by_team_80_plus = analyse_by_team(data_80_plus)
summary_by_hospital_80_plus = analysis_by_team_80_plus.describe().T
summary_by_hospital_80_plus
count mean std min 25% 50% 75% max
thrombolysis_rate 132.0 0.097072 0.037177 0.015184 0.071957 0.090386 0.118358 0.227273
arrivals 132.0 715.295455 324.288269 130.000000 519.000000 693.500000 887.250000 2119.000000
80_plus 132.0 1.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000
rankin_before_stroke_all 132.0 1.582028 0.329839 0.799699 1.355713 1.583800 1.794138 2.464387
nihss_arrival_all 132.0 8.949314 1.154855 5.969027 8.166105 8.990764 9.807674 12.285714
onset_known 132.0 0.646519 0.141493 0.310705 0.543596 0.622715 0.740186 0.992000
known_arrival_within_4hrs 132.0 0.624133 0.093277 0.312377 0.577418 0.627499 0.683352 0.821990
known_arrival_within_4hrs_all 132.0 0.395484 0.069188 0.194872 0.355810 0.392473 0.442737 0.601429
rankin_before_stroke_4hrs 132.0 1.638257 0.335931 0.863830 1.395506 1.650321 1.864107 2.386986
nihss_arrival_4hrs 132.0 10.546849 1.371413 6.688889 9.689962 10.640593 11.557606 13.642157
onset_arrival_mins_mu 132.0 113.772402 7.520809 88.483516 109.819101 113.890154 119.189322 138.846154
onset_arrival_mins_sigma 132.0 52.245901 3.034150 45.279315 50.524577 52.190029 53.860620 67.187195
scan_within_4_hrs 132.0 0.945029 0.032080 0.828221 0.929246 0.947741 0.966349 1.000000
arrival_scan_mins_mu 132.0 43.433208 12.746320 15.293680 33.818753 43.487091 51.689702 90.817518
arrival_scan_mins_sigma 132.0 42.925626 8.063562 22.024223 38.179966 42.849548 48.226897 62.732866
eligable 132.0 0.253801 0.083254 0.047297 0.200000 0.245084 0.312157 0.523077
scan_needle_mins_mu 132.0 38.902157 13.191973 15.808989 29.224436 36.542609 44.672101 89.818182
scan_needle_mins_sigma 132.0 24.271719 9.058096 7.718740 19.062118 22.987181 27.544448 63.516781
arrival_needle_mins_mu 132.0 61.413428 16.096518 26.550000 51.892105 58.293308 68.292676 117.476190
arrival_needle_mins_sigma 132.0 29.143830 9.245836 8.274724 23.842572 27.826304 32.099727 69.019784
onset_needle_mins_mu 132.0 157.229189 15.530805 120.300000 148.107065 154.422078 165.543783 198.809524
onset_needle_mins_sigma 132.0 49.224555 8.075909 25.569296 44.276242 49.327607 52.665629 82.577511
thrombolysis_after_180_min 132.0 0.300602 0.126670 0.000000 0.222222 0.274205 0.362623 0.681818
thrombolysis_after_270_min 132.0 0.015137 0.020425 0.000000 0.000000 0.007547 0.026059 0.095238
summary_by_hospital_80_plus.to_csv('output/pathway_summary_by_hopsital_80_plus.csv')
 # Set all StrokeTeam to same
single_group = data_80_plus.copy()
single_group['StrokeTeam'] = "na"
analysis_all = analyse_by_team(single_group).T
stats_by_age['80+'] = analysis_all[0]

Show comparison of means by age group

stats_by_age.to_csv('output/summary_by_age_group.csv')
stats_by_age
all under_80 80+
stroke_team na na na
thrombolysis_rate 0.118239 0.130445 0.101124
arrivals 226820 132401 94419
80_plus 0.423219 0.0 1.0
rankin_before_stroke_all 1.047315 0.654225 1.598534
nihss_arrival_all 7.46584 6.363859 9.059266
onset_known 0.668596 0.681943 0.64988
known_arrival_within_4hrs 0.586399 0.568081 0.613354
known_arrival_within_4hrs_all 0.392064 0.387399 0.398606
rankin_before_stroke_4hrs 1.059689 0.623704 1.653869
nihss_arrival_4hrs 9.214728 8.178815 10.66594
onset_arrival_mins_mu 111.392722 109.258422 114.30144
onset_arrival_mins_sigma 52.729071 52.840638 52.437656
scan_within_4_hrs 0.94789 0.949953 0.945079
arrival_scan_mins_mu 42.101407 41.584525 42.809469
arrival_scan_mins_sigma 44.793795 44.568632 45.091427
eligable 0.311363 0.346537 0.263179
scan_needle_mins_mu 35.955574 36.509091 34.957163
scan_needle_mins_sigma 28.380323 29.290013 26.633541
arrival_needle_mins_mu 58.816315 60.017234 56.650144
arrival_needle_mins_sigma 35.162372 36.656941 32.180851
onset_needle_mins_mu 155.77768 156.465147 154.537656
onset_needle_mins_sigma 54.035606 55.238587 51.774937
thrombolysis_after_180_min 0.295016 0.303109 0.280419
thrombolysis_after_270_min 0.016726 0.0183 0.013887

Summary figure#

# Set up figure
fig = plt.figure(figsize=(12,14))

# Subplot 1: Histogram of thrombolysis rate
ax1 = fig.add_subplot(321)
x = analysis_by_team['thrombolysis_rate'] * 100
bins = np.arange(0, x.max()+2, 2)
ax1.hist(x, bins=bins, rwidth=0.9)
ax1.set_xlabel('Thrombolysis use (%)')
ax1.set_ylabel('Number of hospitals')
ax1.set_title('A. Thrombolysis use\n(all admissions)')

# Subplot 2: Histogram of thrombolysis rate for patients arriving in 4 hours
ax2 = fig.add_subplot(322)
x = analysis_by_team['eligable'] * 100
bins = np.arange(0, x.max()+5, 5)
ax2.hist(x, bins=bins, rwidth=0.9)
ax2.set_xlabel('Thrombolysis use (%)')
ax2.set_ylabel('Number of hospitals')
ax2.set_title('B. Thrombolysis use\n(arrivals within 4 hours of known onset)')

# Subplot 3: Histogram of proportion of patients with known onset
ax3 = fig.add_subplot(323)
x = analysis_by_team['onset_known'] * 100
bins = np.arange(40, x.max()+5, 5)
ax3.hist(x, bins=bins, rwidth=0.9)
ax3.set_xlabel('Proportion of patients with known onset (%)')
ax3.set_ylabel('Number of hospitals')
ax3.set_title('C. Proportion of patients with known onset')

# Subplot 4: Histogram of mean Arrival to scan times
ax4 = fig.add_subplot(324)
x = analysis_by_team['arrival_scan_mins_mu']
bins = np.arange(0, x.max()+10, 10)
ax4.hist(x, bins=bins, rwidth=0.9)
ax4.set_xlabel('Mean arrival to scan (minutes)')
ax4.set_ylabel('Number of hospitals')
ax4.set_title('''D. Mean arrival to scan time for patients
arriving within 4 hours of known onset and
receiving scan within 4 hours of arrival''')

# Subplot 5: Histogram of mean scan to needle times
ax5 = fig.add_subplot(325)
x = analysis_by_team['scan_needle_mins_mu']
bins = np.arange(0, x.max()+10, 10)
ax5.hist(x, bins=bins, rwidth=0.9)
ax5.set_xlabel('Mean scan to needle (minutes)')
ax5.set_ylabel('Number of hospitals')
ax5.set_title('E. Mean scan to needle time')

# Subplot 6: Histogram of mean arrival to needle times
ax6 = fig.add_subplot(326)
x = analysis_by_team['arrival_needle_mins_mu']
bins = np.arange(0, x.max()+10, 10)
ax6.hist(x, bins=bins, rwidth=0.9)
ax6.set_xlabel('Mean arrival to needle (minutes)')
ax6.set_ylabel('Number of hospitals')
ax6.set_title('F. Mean arrival to needle time')

# Save and show
plt.tight_layout(pad=2)
plt.savefig('output/pathway_summary_six_histograms.jpg', dpi=300)
plt.show();
../_images/01_descriptive_37_0.png

Analysis of stroke severity#

# Restrict to known NIHSS
mask = data['S2NihssArrival'] >= 0
known_NIHSS = data[mask]
counts = pd.DataFrame(known_NIHSS['S2NihssArrival'].value_counts().sort_index())
counts['cum_sum'] = np.cumsum(counts['S2NihssArrival'])
counts
S2NihssArrival cum_sum
0.0 14658 14658
1.0 21117 35775
2.0 27521 63296
3.0 22765 86061
4.0 18955 105016
5.0 14686 119702
6.0 11783 131485
7.0 9334 140819
8.0 7519 148338
9.0 5987 154325
10.0 5322 159647
11.0 4675 164322
12.0 4102 168424
13.0 3649 172073
14.0 3513 175586
15.0 3292 178878
16.0 3190 182068
17.0 3171 185239
18.0 3058 188297
19.0 2953 191250
20.0 2747 193997
21.0 2484 196481
22.0 2316 198797
23.0 2056 200853
24.0 1955 202808
25.0 1673 204481
26.0 1483 205964
27.0 1204 207168
28.0 1040 208208
29.0 705 208913
30.0 579 209492
31.0 439 209931
32.0 398 210329
33.0 284 210613
34.0 247 210860
35.0 191 211051
36.0 169 211220
37.0 139 211359
38.0 159 211518
39.0 77 211595
40.0 146 211741
41.0 40 211781
42.0 311 212092
# Set up figure
fig = plt.figure(figsize=(7,5))
ax1 = fig.add_subplot(111)

total = counts['S2NihssArrival'].sum()
x = list(counts.index)
y1 = counts['S2NihssArrival'] / total
y2 = counts['cum_sum'] / total
ax1.plot(x,y1,color='b')
ax1.tick_params(axis='y', labelcolor='b')
ax1.set_ylim(0, 0.14)
ax1.set_ylabel('Proportion of all patients', color='b')
ax1.set_xlabel('NIHSS')
ax1.set_xlim(0,45)
ax1.set_xticks(np.arange(0,42,5))
ax1.grid(axis='x')

# Add cumsum to second axis
ax2 = ax1.twinx() 
ax2.plot(x,y2,label='Cumulative sum', color='r')
ax2.set_ylim(0,1.02)
ax2.set_yticks(np.arange(0,1.01,0.1))
ax2.set_xticks(np.arange(0,42,5))
ax2.tick_params(axis='y', labelcolor='r')
ax2.set_ylabel('Cumulative proportion of all patients', color='r')
ax2.grid('both')

plt.savefig('output/nihss_count.jpg', dpi=300)
plt.show()
../_images/01_descriptive_40_0.png

Analyse onset-to-arrival times#

All arrivals

# Count patients with determined NIHSS
total_with_determined_nihss = np.sum(data['S2NihssArrival'] >= 0)
proportion_with_determined_nihss = np.mean(data['S2NihssArrival'] >= 0)

# Restrict to known onset
f = lambda x: x in ['Precise', 'Best estimate']
mask = data['S1OnsetTimeType'].apply(f)
data_known_onset = data[mask]
prop_known_onset_all = mask.mean()

# Get counts of arrival times, up to 12 hours, in 30 min bins
bins = np.arange(0, 721, 30)
arrivals_all, _ = np.histogram(data_known_onset['S1OnsetToArrival_min'], bins)
prop_arrivals_in_12_hours = np.sum(arrivals_all) / mask.sum()
df_all_arrivals = pd.DataFrame()
df_all_arrivals['Arrival bin (upper)'] = bins[1:]
df_all_arrivals.set_index('Arrival bin (upper)', inplace=True)
df_all_arrivals['Counts'] = arrivals_all
df_all_arrivals['Prop known onset'] = arrivals_all / mask.sum()
df_all_arrivals['Cumulatative prop'] = np.cumsum(df_all_arrivals['Prop known onset'])

print('All arrivals:')
print('-------------')
print(f'Proporotion of arrivals with determmined NIHSS: {proportion_with_determined_nihss:0.3}')
print(f'Proportion of arrivals with known stroke onset: {prop_known_onset_all:0.3f}')
print(f'Proportion known stroke onset arriving within 12 hours: {prop_arrivals_in_12_hours:0.3f}')
print (df_all_arrivals)
All arrivals:
-------------
Proporotion of arrivals with determmined NIHSS: 0.935
Proportion of arrivals with known stroke onset: 0.669
Proportion known stroke onset arriving within 12 hours: 0.799
                     Counts  Prop known onset  Cumulatative prop
Arrival bin (upper)                                             
30                     1819          0.011995           0.011995
60                    11283          0.074401           0.086396
90                    23536          0.155198           0.241594
120                   18806          0.124008           0.365603
150                   12402          0.081780           0.447382
180                    8791          0.057969           0.505351
210                    6731          0.044385           0.549736
240                    5283          0.034837           0.584572
270                    4344          0.028645           0.613217
300                    3653          0.024088           0.637305
330                    3133          0.020659           0.657965
360                    2767          0.018246           0.676211
390                    2486          0.016393           0.692603
420                    2109          0.013907           0.706510
450                    1968          0.012977           0.719488
480                    1690          0.011144           0.730632
510                    1599          0.010544           0.741175
540                    1454          0.009588           0.750763
570                    1376          0.009073           0.759837
600                    1235          0.008144           0.767980
630                    1202          0.007926           0.775907
660                    1163          0.007669           0.783575
690                    1136          0.007491           0.791066
720                    1158          0.007636           0.798702

Mild stroke (NIHSS <= 5)

# Proportion mild stroke
mild = data['S2NihssArrival'] <=5
prop_mild = mild.sum()/data.shape[0]
print (f'Proportion mild {prop_mild:0.2f}')
Proportion mild 0.53
# Restrict to NIHSS <5
mask = data['S2NihssArrival'] <=5
data_mild = data[mask]
proportion_mild_stroke = mask.sum() / total_with_determined_nihss

# Restrict to known onset
f = lambda x: x in ['Precise', 'Best estimate']
mask = data_mild['S1OnsetTimeType'].apply(f)
data_known_onset = data_mild[mask]
prop_known_onset_mild = mask.mean()

# Get counts of arrival times, up to 12 hours, in 30 min bins
bins = np.arange(0, 721, 30)
arrivals_all, _ = np.histogram(data_known_onset['S1OnsetToArrival_min'], bins)
prop_arrivals_in_12_hours = np.sum(arrivals_all) / mask.sum()
df_mild_arrivals = pd.DataFrame()
df_mild_arrivals['Arrival bin (upper)'] = bins[1:]
df_mild_arrivals.set_index('Arrival bin (upper)', inplace=True)
df_mild_arrivals['Counts'] = arrivals_all
df_mild_arrivals['Prop known onset'] = arrivals_all / mask.sum()
df_mild_arrivals['Cumulatative prop'] = np.cumsum(df_mild_arrivals['Prop known onset'])

print('Mild stroke (NIHSS <= 5):')
print('-------------------------')
print(f'Proportion of all arrivals, with determined NIHSS, with mild stroke: {proportion_mild_stroke:0.3f}')
print(f'Proportion of arrivals with known stroke onset: {prop_known_onset_mild:0.3f}')
print(f'Proportion known stroke onset arriving within 12 hours: {prop_arrivals_in_12_hours:0.3f}')
print (df_mild_arrivals)
Mild stroke (NIHSS <= 5):
-------------------------
Proportion of all arrivals, with determined NIHSS, with mild stroke: 0.564
Proportion of arrivals with known stroke onset: 0.645
Proportion known stroke onset arriving within 12 hours: 0.723
                     Counts  Prop known onset  Cumulatative prop
Arrival bin (upper)                                             
30                      810          0.010485           0.010485
60                     3767          0.048760           0.059245
90                     8347          0.108043           0.167288
120                    7769          0.100562           0.267850
150                    5840          0.075593           0.343443
180                    4290          0.055530           0.398972
210                    3464          0.044838           0.443810
240                    2807          0.036334           0.480144
270                    2369          0.030664           0.510808
300                    2010          0.026017           0.536826
330                    1760          0.022781           0.559607
360                    1545          0.019998           0.579605
390                    1409          0.018238           0.597844
420                    1240          0.016051           0.613894
450                    1204          0.015585           0.629479
480                     975          0.012620           0.642099
510                     978          0.012659           0.654758
540                     895          0.011585           0.666343
570                     843          0.010912           0.677255
600                     759          0.009824           0.687079
630                     743          0.009617           0.696697
660                     697          0.009022           0.705719
690                     681          0.008815           0.714533
720                     682          0.008828           0.723361

Non-mild stroke (NIHSS > 5)

# Proportion non-mild stroke
non_mild = data['S2NihssArrival'] >5
prop_non_mild = non_mild.sum()/data.shape[0]
print (f'Proportion non-mild {prop_non_mild:0.2f}')
Proportion non-mild 0.41
# Restrict to NIHSS >5
mask = data['S2NihssArrival'] >5
data_not_mild = data[mask]
proportion_not_mild_stroke = mask.sum() / total_with_determined_nihss

# Restrict to known onset
f = lambda x: x in ['Precise', 'Best estimate']
mask = data_not_mild['S1OnsetTimeType'].apply(f)
data_known_onset = data_not_mild[mask]
prop_known_onset_not_mild = mask.mean()

# Get counts of arrival times, up to 12 hours, in 30 min bins
bins = np.arange(0, 721, 30)
arrivals_all, _ = np.histogram(data_known_onset['S1OnsetToArrival_min'], bins)
prop_arrivals_in_12_hours = np.sum(arrivals_all) / mask.sum()
df_not_mild_arrivals = pd.DataFrame()
df_not_mild_arrivals['Arrival bin (upper)'] = bins[1:]
df_not_mild_arrivals.set_index('Arrival bin (upper)', inplace=True)
df_not_mild_arrivals['Counts'] = arrivals_all
df_not_mild_arrivals['Prop known onset'] = arrivals_all / mask.sum()
df_not_mild_arrivals['Cumulatative prop'] = np.cumsum(
    df_not_mild_arrivals['Prop known onset'])

print('Non-mild stroke (NIHSS >5):')
print('-------------------------')
print(f'Proportion of arrivals with known stroke onset: {prop_known_onset_not_mild:0.3f}')
print(f'Proportion of all arrivals, with determined NIHSS, with NIHSS >5: {proportion_not_mild_stroke:0.3f}')
print(f'Proportion known stroke onset arriving within 12 hours: {prop_arrivals_in_12_hours:0.3f}')
print (df_not_mild_arrivals)
Non-mild stroke (NIHSS >5):
-------------------------
Proportion of arrivals with known stroke onset: 0.715
Proportion of all arrivals, with determined NIHSS, with NIHSS >5: 0.436
Proportion known stroke onset arriving within 12 hours: 0.883
                     Counts  Prop known onset  Cumulatative prop
Arrival bin (upper)                                             
30                      915          0.013852           0.013852
60                     6813          0.103141           0.116993
90                    13655          0.206722           0.323715
120                    9899          0.149860           0.473575
150                    5874          0.088926           0.562501
180                    4058          0.061434           0.623935
210                    2920          0.044206           0.668140
240                    2238          0.033881           0.702021
270                    1756          0.026584           0.728605
300                    1421          0.021512           0.750117
330                    1220          0.018469           0.768587
360                    1067          0.016153           0.784740
390                     949          0.014367           0.799107
420                     750          0.011354           0.810461
450                     654          0.009901           0.820362
480                     631          0.009553           0.829914
510                     537          0.008130           0.838044
540                     473          0.007161           0.845205
570                     465          0.007040           0.852244
600                     406          0.006146           0.858391
630                     394          0.005965           0.864355
660                     398          0.006025           0.870381
690                     396          0.005995           0.876376
720                     413          0.006252           0.882628

NIHSS >10

# Restrict to NIHSS >10
mask = data['S2NihssArrival'] >10
data_nihss_11plus = data[mask]
proportion__11plus = mask.sum() / total_with_determined_nihss

# Restrict to known onset
f = lambda x: x in ['Precise', 'Best estimate']
mask = data_nihss_11plus['S1OnsetTimeType'].apply(f)
data_known_onset = data_nihss_11plus[mask]
prop_known_onset_11plus = mask.mean()

# Get counts of arrival times, up to 12 hours, in 30 min bins
bins = np.arange(0, 721, 30)
arrivals_all, _ = np.histogram(data_known_onset['S1OnsetToArrival_min'], bins)
prop_arrivals_in_12_hours = np.sum(arrivals_all) / mask.sum()
df_arrivals_11plus = pd.DataFrame()
df_arrivals_11plus['Arrival bin (upper)'] = bins[1:]
df_arrivals_11plus.set_index('Arrival bin (upper)', inplace=True)
df_arrivals_11plus['Counts'] = arrivals_all
df_arrivals_11plus['Prop known onset'] = arrivals_all / mask.sum()
df_arrivals_11plus['Cumulatative prop'] = np.cumsum(
    df_arrivals_11plus['Prop known onset'])

print('Non-mild stroke (NIHSS >10):')
print('-------------------------')
print(f'Proportion of arrivals with known stroke onset: {prop_known_onset_11plus:0.3f}')
print(f'Proportion of all arrivals, with determined NIHSS, with NIHH >10: {proportion__11plus:0.3f}')
print(f'Proportion known stroke onset arriving within 12 hours: {prop_arrivals_in_12_hours:0.3f}')
print (df_arrivals_11plus)
Non-mild stroke (NIHSS >10):
-------------------------
Proportion of arrivals with known stroke onset: 0.726
Proportion of all arrivals, with determined NIHSS, with NIHH >10: 0.247
Proportion known stroke onset arriving within 12 hours: 0.910
                     Counts  Prop known onset  Cumulatative prop
Arrival bin (upper)                                             
30                      543          0.014264           0.014264
60                     4644          0.121992           0.136256
90                     8890          0.233529           0.369786
120                    6076          0.159609           0.529395
150                    3409          0.089550           0.618945
180                    2281          0.059919           0.678864
210                    1586          0.041662           0.720526
240                    1222          0.032100           0.752627
270                     951          0.024982           0.777608
300                     739          0.019413           0.797021
330                     641          0.016838           0.813859
360                     549          0.014422           0.828281
390                     466          0.012241           0.840522
420                     357          0.009378           0.849900
450                     305          0.008012           0.857912
480                     326          0.008564           0.866476
510                     276          0.007250           0.873726
540                     228          0.005989           0.879715
570                     208          0.005464           0.885179
600                     190          0.004991           0.890170
630                     173          0.004544           0.894715
660                     192          0.005044           0.899758
690                     188          0.004939           0.904697
720                     197          0.005175           0.909872
# Set up figure
fig = plt.figure(figsize=(7,5))
ax = fig.add_subplot(111)
x = df_all_arrivals.index
x -= 15 # plot at centre of bin
y1 = df_all_arrivals['Cumulatative prop']
y2 = df_mild_arrivals['Cumulatative prop']
y3 = df_not_mild_arrivals['Cumulatative prop']
y4 = df_arrivals_11plus['Cumulatative prop']

ax.plot(x, y1, label = 'All arrivals')
ax.plot(x, y2, label = 'NIHSS <= 5')
ax.plot(x, y3, label = 'NIHSS >5')
ax.plot(x, y4, label = 'NIHSS >10')

ax.set_xlabel('Onset to arrival (minutes)')
ax.set_ylabel('Proportion of patients (with known onset)')
ax.set_ylim(0, 720)
ax.set_ylim(0, 1.0)
ax.set_yticks(np.arange(0, 1.01, 0.1))

ax.grid()

text = f'''Proportion all arrivals with known onset {prop_known_onset_all:0.3}
Proportion NIHSS <=5 arrivals with known onset {prop_known_onset_mild:0.3}
Proportion NIHSS >5 arrivals with known onset {prop_known_onset_not_mild:0.3}
Proportion NIHSS >10 arrivals with known onset {prop_known_onset_11plus:0.3}'''
props = dict(boxstyle='square', facecolor='white', alpha=1.0)
plt.text(175, 0.05, text, bbox=props)

ax.legend(loc='upper left')

plt.savefig('output/onset_to_arrival.jpg', dpi=300)

plt.show()
../_images/01_descriptive_52_0.png

Queries on time of arrival and NIHSS for patients who receive thrombolysis#

See also later section on comparison of average values for patients who receive thrombolysis and those that do not (though that data is for patients who arrive within 4 hours of known stroke onset)

data_thrombolysed = data[data['S2Thrombolysis'] == 'Yes']
thrombolysed = dict()

# Onset known
onset_known = (data_thrombolysed['S1OnsetTimeType'] == 'Precise') | (data_thrombolysed['S1OnsetTimeType'] == 'Best estimate')
thrombolysed['onset known'] = onset_known.mean()

# Arrival within 4 hours
arrive_4_hours = data_thrombolysed['S1OnsetToArrival_min'] <= 240
thrombolysed['arrive within 4 hours'] = arrive_4_hours.mean()

# Arrival within 6 hours
arrive_6_hours = data_thrombolysed['S1OnsetToArrival_min'] <= 360
thrombolysed['arrive within 6 hours'] = arrive_6_hours.mean()

# NIHSS >5
nihss_greater_5 = data_thrombolysed['S2NihssArrival'] >5
thrombolysed['nihss 6+'] = nihss_greater_5.mean()
nihss_greater_5_arrival_4_hrs = nihss_greater_5 & arrive_4_hours
thrombolysed['nihss 6+ and arrive in 4 hours'] = nihss_greater_5_arrival_4_hrs.mean()
nihss_greater_5_arrival_6_hrs = nihss_greater_5 & arrive_6_hours
thrombolysed['nihss 6+ and arrive in 6 hours'] = nihss_greater_5_arrival_6_hrs.mean()

# NIHSS >10
nihss_greater_10 = data_thrombolysed['S2NihssArrival'] >10
thrombolysed['nihss 11+'] = nihss_greater_10.mean()
nihss_greater_10_arrival_4_hrs = nihss_greater_10 & arrive_4_hours
thrombolysed['nihss 11+ and arrive in 4 hours'] = nihss_greater_10_arrival_4_hrs.mean()
nihss_greater_10_arrival_6_hrs = nihss_greater_10 & arrive_6_hours
thrombolysed['nihss 11+ and arrive in 6 hours'] = nihss_greater_10_arrival_6_hrs.mean()

thrombolysed = pd.Series(thrombolysed)
thrombolysed
onset known                        0.988926
arrive within 4 hours              0.979045
arrive within 6 hours              0.987211
nihss 6+                           0.739252
nihss 6+ and arrive in 4 hours     0.723330
nihss 6+ and arrive in 6 hours     0.729520
nihss 11+                          0.451247
nihss 11+ and arrive in 4 hours    0.440807
nihss 11+ and arrive in 6 hours    0.444573
dtype: float64

General observations#

  • There are 239,505 admissions (2016-2018) to 132 stroke teams that receive at least 300 admissions and provide thrombolysis to at least 10 patients over the course of three years (2016-2018).

  • 5.3% of patients have an in-hospital stroke onset; 12.3% receive thrombolysis. 94.7% of patients have an out-of-hospital stroke onset; 11.8% receive thrombolysis.

The following statistic apply to out-of-hospital onset stroke patients only

  • 43% of arrivals are aged 80 or more.

  • 67% of all patients have a determined stroke time of onset, 60% of whom arrive within 4 hours of known stroke onset. 40% of all arrivals arrive within 4 hours of known stroke onset.

  • The average NIHSS (stroke severity) is 7.4

Of those arriving within 4 hours of known stroke onset:

  • The average onset-to-arrival time is 111 minutes.

  • 95% receive a scan within 4 hours of arrival, with an average arrival-to-scan time of 43 minutes.

  • 30% of those who receive a scan within 4 hours of known stroke onset, and 11.8% of all arrivals, receive thrombolysis. The average scan-to-needle time is 40 minutes, the average arrival-to-needle time is 63 minutes, and the average onset-to-needle time is 158 minutes.

On inter-hospital variation:

  • Thrombolysis use varies from 1.5% to 24.3% of all patients, and 7.3% to 49.7% of patients arriving within 4 hours of known stroke onset.

  • The proportion of determined stroke onsets ranges from 34% to 99%.

  • The proportion of patients arriving within 4 hours of known stroke onset ranges from 22% to 56%.

  • The proportion of patients scanned within 4 hours of arrival ranges from 85% to 100%.

  • Average arrival-to-scan (for those arriving within 4 hours of known stroke onset and scanned within 4 hours of arrival) ranges from 19 to 93 minutes.

  • Average arrival-to-needle time varies from 26 to 111 minutes.

  • The proportion of patients aged 80+ varies from 29% to 58%.

  • The average NIHSS (stroke severity) ranges from 6.1 to 11.7.

On differences by age group (under age 80 years vs 80+):

  • 10.1% of arrivals aged 80+ receive thrombolysis, c.f. 13.0% of those under age 80.

  • 39% of arrivals aged 80+ arrive within 4 hours of known stroke onset, c.f. 40% of those under age 80.

  • The average disability (Rankin) before stroke is 1.7 for those aged 80+, c.f. 0.6 for those under age 80.

  • The average stroke severity (NIHSS) on arrival is 10.7 for those aged 80+, c.f. 8.2 for those under age 80.

  • Of those scanned within 4 hours, 26.3% of those aged 80+ receive thrombolysis, c.f. 34.7% of those under age 80.

On onset-to-arrival times

  • Those with non-mild stroke (NINHSS >5) tend to arrive earlier than mild stroke (NIHSS <=5). For example, of those with known stroke onset time, 70% and 79% of those with non-mild stroke arrive within 4 and 6 hours from onset. The same results for mild stroke patients are 48% and 58%. Non-mild stroke are also more likely to have a determined time of onset compared to mild stroke (72% vs 65%).