ESA_ED_Crowding

所属分类:数据挖掘/数据仓库
开发工具:R
文件大小:62KB
下载次数:0
上传日期:2022-11-21 23:09:44
上 传 者sh-1993
说明:  经济和战略分析团队,在英国国民保健制度首席数据和分析官的领导下工作,已经发展...
(The Economics and Strategic Analysis Team, working under the Chief Data and Analytics Officer at NHS England have developed a model to investigate Emergency Department crowding, building on previous work conducted within the team. This package provides a user-friendly, database-agnostic way for other teams at NHSE and across the NHS system to)

文件列表:
DESCRIPTION (872, 2022-11-22)
ESAedcrowding.Rproj (356, 2022-11-22)
LICENSE (1068, 2022-11-22)
NAMESPACE (61, 2022-11-22)
NEWS.md (1070, 2022-11-22)
OPEN-GOVERNMENT-LICENSE (6793, 2022-11-22)
R (0, 2022-11-22)
R\ESAAcuity.R (1818, 2022-11-22)
R\ESAAdmittedAggregated.R (21608, 2022-11-22)
R\ESADataFlag.R (921, 2022-11-22)
R\ESAEDAggregated.R (11124, 2022-11-22)
R\ESAEDPatientLevel.R (9887, 2022-11-22)
R\ESAExternalData.R (3247, 2022-11-22)
R\ESAModel.R (44529, 2022-11-22)
R\ESAModelScenario.R (351, 2022-11-22)
R\ESAQueue.R (558, 2022-11-22)
R\ESASlot.R (852, 2022-11-22)
R\utils.R (4534, 2022-11-22)
demo (0, 2022-11-22)
demo\working_example.R (21885, 2022-11-22)
man (0, 2022-11-22)
man\ESAAdmittedAggregated.Rd (5974, 2022-11-22)
man\ESADataFlag.Rd (2010, 2022-11-22)
man\ESAEDAggregated.Rd (5676, 2022-11-22)
man\ESAEDPatientLevel.Rd (2505, 2022-11-22)
man\ESAModel.Rd (5257, 2022-11-22)
man\ESAModelScenario.Rd (1595, 2022-11-22)
man\ESAQueue.Rd (1482, 2022-11-22)
man\ESASlot.Rd (1850, 2022-11-22)
man\getDataFromODBC.Rd (490, 2022-11-22)
man\is.Date.Rd (352, 2022-11-22)
man\searchWithin.Rd (761, 2022-11-22)
man\unique.vector.Rd (435, 2022-11-22)
man\vector.endsWith.Rd (388, 2022-11-22)

![status: active](https://github.com/GIScience/badges/raw/master/status/active.svg) [![Issues][issues-shield]][license-url] [![Forks][forks-shield]][forks-url] [![Stars][stars-shield]][stars-url] [![MIT License][license-shield]][license-url]

NHS Emergency Department Crowding Model

The Economics and Strategic Analysis Team, working under the Chief Data and Analytics Officer (CDAO) at NHS England have developed a model to investigate Emergency Department (ED) crowding. This builds on previous analysis conducted within the team. This model aims to take a whole system approach, looking at drivers of crowding pre-hospital, within A&E, rest of hospital and wider healthcare capacity.
Report Bug Request Feature

Table of Contents
  1. Aims
  2. Motivation & Contribution
  3. What is ED crowding, and why is it important?
  4. How do we measure ED crowding?
  5. Our model
  6. Packages
  7. Usage
  8. Data Sources
  9. Data flows
  10. Installing the package
  11. Getting Started
  12. A note on additional variables
  13. Additional Considerations
  14. Contributing
  15. License
  16. Contact
__Note:__ _No data is shared in this repository._ ## Aims The purpose of the code is for other users within the NHS system, to take this work forward. We therefore have developed using the R programming language. The main interface for this analysis is designed to be as simple as possible, and has been developed in a database-agnostic manner. The package is built in a manner to allow user customizability, for example, one may wish to explore the effect of factors on ED crowding over the whole day, rather than for specific slots.

(back to top)

## Motivation & Contribution ```mermaid flowchart TD; subgraph contrib[Our Contribution] %% setup the nodes contrib1(["To best of our knowledge, our analysis quantifies robustly, for the first time, the effects of key factors on ED Crowding"]) contrib2["1. We isolate and quantify the effect of each factor of crowding we consider"] contrib3["2. We develop 3 new ED crowding metrics"] %% link the nodes together contrib1---contrib2 contrib2---contrib3 end subgraph quest["What drives crowding in Type 1 ED departments"] quest1["Our analysis aims to take a whole system approach, looking at pre-hospital, within ED, rest of hospital and wider healthcare capacity"] end subgraph aims["Project Aims"]; aims1(["Availability of new, more timely data on EDs - we use ECDS data from FasterSUS with lag of 3 days"]); aims2(["Policy shift away from staying times to crowding, led by the Clinical Review of Standards"]); aims3(["Evidence gap - we may know what we think is driving crowding, but we do not know to what extend"]); aims1-->aims2; aims2-->aims3; end contrib-->quest quest-->aims ``` ## What is ED crowding, and why is it important? Crowding occurs in ED when patients are stuck in a queue. Previous research shows that crowding: - is associated with increased patient mortality - reduces the quality of care - compromises patient privacy and dignity - compromises the ability to deliver basic nursing care During winter 2019/20 (pre-COVID-19), pressure on acute hospital bed base resulted in unacceptable crowding in EDs, and, in some cases, patients being cared for in inappropriate environments (_corridor care_). COVID-19 has made ED crowding worse, requiring longer, deeper cleans, and social distancing Crowding can occur for three types of ED patients - **Majors** - patients with most complicated injuries or illnesses e.g. shortness of breath or hip injuries - **Minors** - least seriously injured or ill patients, with injuries such as ankle or wrist injuries - **Resus** - crowding expected to be less of a problem in **resus** as these are the most seriously injured or ill patients

(back to top)

## How do we measure ED crowding? After engaging with stakeholders, we decided to model ED crowding using three metrics. The first two metrics are seperately calculated for each type of patient (**majors**/**minors**/**resus**) and for each time slot in the day. The third metric is only estimated for **majors** and **resus**. **Overall Crowding**: ***Number of patients staying at ED***. This metric counts the number of patients who are present at each time slot irrespective of whether they were discharged in a later slot, or arrived in an earlier one. For example, it will count the number of majors patients at an ED site, on a given day (for a given time slot) as long as they were present in that time slot/day/site, and irrespective of their staying time and arrival/discharge times. **6 hours + stays**: ***Number of patients staying longer than 6 hours at ED***. This is a subset of the overall crowding metric. It counts the number of patients who would have been staying for 6+ hours by the end of the slot, or their discharge time, whichever is earlier. **Cubicle crowding**: ***Number of majors and resus patients staying in the ED per cubicle***. We sum the overall crowding metric for majors and resus patients (for a given site/day/time slot) and divide by the number of majors + resus cubicles for that site.

(back to top)

## Our model Econometric analysis enables us to isolate the impact of the different factors on crowding in ED's. **This allows us to show the effect of each individual variable once we keep the values of the other variables fixed** We create separate models to look at three crowding metrics for three patient types (**majors**, **minors**, **resus**). We divide the day into six 4-hour slots. We estimate the effect of the various factors below on '_overall crowding_' and '_6hr+ stays_' for each slot and type of patient. We also look at the effect of the various factors on '_cubicle crowding_' for majors+resus patients (and each of the 6 time slots). | Pre-hospital | Controls & Time effects | Within ED | Rest of Hospital Capacity | Wider Healthcare Capacity | | :---- | :--- | :--- | :--- | :--- | | Arrival mode | Patients over 75 (frailty proxy) | Complaint (MAU) | G&A bed occupancy | Fit for discharge patients not discharged | | Referral source | Ethnicity | Investigation | ACC bed occupancy | | | | Deprivation | Diagnosis | Number of long-stay patients (>=21d) | | | | Sex | | Admitted patient transfers between site/specialty/both | | | | Day of week | | Number inpatients in each specialty | | | | Bank Holiday | | Share of admitted patients from ED | | | | Month | | | | **There may be unobserved variation between sites, and while we cannot directly measure the effect of those factors on crowding, as long as they do not vary much over time, our modelling approach minimises the danger that our results are affected by their non-inclusion.**

(back to top)

## Packages | Package Name | Purpose | | ------------- |:----------------------------------------: | | data.table | alternative to R's default data.frame | | R6 | enable object-orientated programming | | odbc | interface to ODBC drivers | | fixest | estimate fixed effects econometric models | | ggplot2 | used for some plots | | gt (suggested)| create HTML tables from regression tables |

(back to top)

## Usage We rely on hospital activity data from the Secondary Uses Service repository. However, the user is free to rely on their own data-sources, provided the relevant data points are present. We implement R6 classes to clean, prepare, derive and aggregate data for both (admitted) inpatients, and emergency department attendances. Whilst some level of data cleaning is present, when using data other than SUS, it is recommended that data be adequately prepared beforehand. Furthermore, it is easy to supplement the aforementioned datasets with other relevant data, we do so utilising NHS England Situation Reports (SitReps).

(back to top)

## Data Sources | Name | Location | Purpose | Notes | Columns Required | | :--: | :----- | :--- | :--- | :--- | | Admitted Patient Care Episodes (APCE) | fasterSUS, NCDR | Allow derivation of variables relating to inpatients e.g. transfers between site/specialty/both, number of inpatients within specialties, and long-stay patients | As only episodes which have reached their conclusion (e.g. no un-finished episodes) are present, sufficient time should be allowed for episodes to adequately conclude (e.g. latest date analysed could be 30 days previous to today for example). There should also be a buffer preceeding the time period of analysis, to capture patients who already have been admitted (if selecting episodes by the episode start date; we use 21 days preceeding). Note that we in our modelling, we lag specialty counts by 1 day (e.g. specialty count in the previous day) to avoid issues of reverse-causality | APC_Ident, Episode_Start_Date, Episode_End_Date, Discharge_Date, Episode_Number, Der_Pseudo_NHS_Number, Main_Speciality_Code, Provider_Code, Der_Provider_Site_Code, Hospital_Spell_No | | Emergency Care Dataset (ECDS) | fasterSUS, NCDR | Primary dataset containing all ED attendances | We require the 24 SNOMED_CT Investigation codes via the EC_Investigation table, and the 24 SNOMED_CT Diagnosis codes via the EC_Diagnosis table | all | | NHSD Ethnicity + Segmentation | COVID-19 PSDM | Provides better ethnicity data coverage. | Note that this table is in some ways optional, as ECDS does contain an ethnicity field. We merge the NHSD ethnicity collection with Segmentation (with the former prioritized over the latter) | Derived, 2001 ethnic category code | | ODS Provider Hierarchies | NHSE Reference tables, NCDR | Map NHS Providers to their NHSE Regions | | Organisation_Code, Region_Name | | Holiday days (Other Dates) | NHSE Reference tables, NCDR | Determine whether a given day is a holiday | | Date, derived field based on Holiday_Desc | | Discharge Sitrep | Discharge Daily Sitrep, COVID-19 PSDM| Derive the discharge rate (the proportion of those who were fit to be discharged, who were discharged) | Indicator of wider-system pressures e.g. social care | Period_DateTime_Start, Org_Code, Metric_ID, Metric_Value | | Bed Occupancy | Strategic Insights Platform (SIP) | Derive Adult Critical Care (ACC) and General & Acute (G&A) bed occupancy
($\frac{\text{occupied beds}}{\text{open beds}}$) | These figures can be alternatively obtained via the Acute SitRep in the COVID-19 PSDM. We bucket each type of bed occupancy into 0-80%, then one percentage point increments until 100% bed occupancy. Modeling on regions (or smaller) may require larger bucket sizes (e.g. five percentage point buckets) due to the small amount of trusts relative to the number of levels. Note again that in our modeling, we use the previous day's bed occupancy levels rather than that of the present day. This is to mitigate any potential reverse-causality. | G&ATotalBedsOpen, G&ATotalBedsOccupied, ACCBedsOpen, ACCBedsOccupied, OrgCode, Period, Site_Code | | Cubicles | Internally via Get It Right First Time (GIRFT) | Number of (majors and resus) cubicles | Note this datasource is static (e.g. no variation over time) | |

(back to top)

## Data flows Below is a summary of the data flows for those data sources used. Note the `User Supplied Data` box, this represents any additional data the user wishes to utilize within their modeling. These are required to be at Provider/Provider Site and day level. ```mermaid flowchart TD; %% create nodes apce[("Admitted Patient Care Episodes (APCE)")] ecds[("Emergency Care Dataset")] eth[("NHSD Ethnicity Collection")] seg[("Segmentation Output (B2H)")] mergedEth[("Merged Ethnicities")] provHier[("ODS Provider Hierarchies")] hols[("Holiday dates")] bedOcc[("Bed Occ - SIP/UEC SitRep")] disch[("Discharge Sitrep")] apceSiteDay[("APCE aggregated by Site & Day")] ecdsSiteDay[("ECDS aggregated by Site & Day")] final[("Final Dataset")] %% draw lines for nodes apce --aggregation-->apceSiteDay ecds --aggregation-->ecdsSiteDay ecdsSiteDay ==>final apceSiteDay--"merge"-->final eth-->mergedEth seg--"merge"-->mergedEth mergedEth--"merge"-->final provHier--merge-->final hols--merge-->final bedOcc--merge-->final disch--merge-->final final==>id["Modelling"] user("User Supplied Data")--merge--->final ```

(back to top)

## Installing the package Our package can be installed directly from github using the **devtools** package. ```r devtools::install_github('NHSEngland/ESA_ED_Crowding') ``` and can be loaded as with any other R package, `library(ESAedcrowding)` ## Getting Started ### Class overview ```mermaid classDiagram class ESADataFlag { + name: character + columns: vector + search: vector } class ESAAcuity { +other.acuities():char-vec } class ESASlot { +slotID: character +slotHours: num-vec +maxMins: integer +maxHour: integer } class ESAQueue { +name: character +offset.hours: integer +offset.mins: integer } class ESAEDPatientLevel { +data: data.table -hasRunSlots: boolean -acuities: list~ESAAcuity~ -flags: list~ESADataFlags~ +getAcuities(): list~ESAAcuity~ +getFlags(): list~ESADataFlags~ -create.flags(flags): data.table -create.slots(slots,queues,col.arrival,col.departure,col.uniqueIdent): data.table } class ESAEDAggregated { +data: data.table -esaPatientLevel: ESAPatientLevel -acuity: ESAAcuity -queue: ESAQueue -slots: list~ESASlots~ -identifier: character -providerSite: character -provider: character +mergeAdmitted(esaAdmittedAggregated): data.table +getAvailableVars(): char-vec +getAcuity(): character +getIdentifier(): character +getESAPatientLevel(): ESAPatientLevel +getQueue(): ESAQueue +getSlots(): list~ESASlots~ +getProviderSite(): character +getDate(): character +getProvider(): character -doAggregation(provider.col,providerSite.col,queue,cubicles,cubicles.site,cubicles.date,cubicles.col):data.table } class ESAAdmittedAggregated { -cleanedRawData: data.table -providerSite: character -col.episodeStartDate: character -col.episodeEndDate: character -col.episodeSpecialty: character -col.spellIdent: character -col.episodeNo: character -col.episodeID: character +specialties(): data.table +transfers(): data.table +longStayPatients_days21(): data.table +longStayPatients_daysAll(): data.table +getRawCleanedData(): data.table +getProviderSite(): character +getDateCol(): character -cleanData(data,episodeStartDate,episodeEndDate,dischargeDate,minDate,maxDate,patientID,episodeNo,spellHospIdent,kSpellIdent): data.table -calculateTransfers(data,siteCode,specialty,episodeNo,kSpellIdent,episodeEndDate,episodeStartDate): data.table -specialtyCounts(data,kSpellIdent,siteCode,episodeID,episodeStartDate,episodeEndDate,episodeSpecialty,episodeNo): -longStayPatients_allDays(data,episodeStartDate,episodeEndDate,siteCode): data.table -longStayPatients_21Days(data,episodeStartDate,episodeEndDate,siteCode): data.table } class ESAModel { - esaEDObj: ESAEDAggregated - modelResults.all: list~data.table~ - modelResultsWide.all: list~data.table~ - modelRegression.datasets: list~data.table~ - bedOccupancyVars: vector~character~ - modelType: character - modelObjects: list~fixestObjects~ +runScenario(): NULL +results.slot.avg(sig,min.slot.sig): data.table +getResults(sig,min.slot.sig,useSampleAvgs,from,to): data.table +getCoefficientPlots(exclusions): list~ggplot~ +getBedOccupancyPlots(sig,min.slot.sig,useSampleAvgs,groupSize,reverse): list~ggplot,data.table~ +getRegressionDatasets(): list~data.table~ +getSampleAvgs(sampleAvg): data.table +getRegressionTable(exclusions): data.frame -getFormulas(obj,bedOccupancy,slotVars,nonSlotVars,fixedEffects): list~formula~ -runModels(obj,formuli,model.type,printSummary): data.table -model.results.avg(sig,min.slot.sig): data.table -model.sample.averages(only.modelled): data.table -getModelSuff(obj): character } %% combined all the classes together ESADataFlag--|>ESAAcuity ESAEDPatientLevel ..>ESAAcuity ESAEDPatientLevel ..>ESADataFlag %% ESAEDAggregated has a dependency on both ESAQueue and ESASlot ESAEDAggregated ..> ESAQueue ESAEDAggregated ..> ESASlot ESAEDAggregated ..|> ESAEDPatientLevel ESAModel ..|> ESAEDAggregated ESAAdmittedAggregated --> ESAEDAggregated ``` ### Slots We split the day into 6 four hour slots - these are represented through `ESASlot` objects. ```r slots <- list(slot1=ESASlot$new(slotID='slot_1', slotHours=0:3), slot2=ESASlot$new(slotID='slot_2', slotHours=4:7),...) ``` Users are free to customise this; whether you want to run the model considering a day in its entirety, or some other breakdown. ```r slots <- list(slot1=ESASlot$new(slotID='slot_1', slotHours=0:23) ``` ### Queues We can specify queue objects (`ESAQueue`), which allow running models looking at patients who have stayed in the ED for a minimum amount of time - we look at 6 hour + stays. However, users may wish to investigate what factors affects those waiting over 12 hours, in alignment with the Clinical Review of Standards. This can be achieved by setting the `offset.hours` argument to `12`. ```r queues <- list(longQueue=ESAQueue$new(name='long', offset.hours=6)) ``` ### ED attendance variables Our model is daily site-level panel model, we therefore define flags for our desired variables, and aggregate up and calculate ***the share*** of ED attendances having that characteristic. We can specify `ESADataFlag` objects which allow defining the column(s) and search value(s) for each var ... ...

近期下载者

相关文件


收藏者