NYU ED Classification
Overview
The NYU ED Classification data mart classifies emergency department encounters using the NYU ED Algorithm, also known as the Billings algorithm. The algorithm was developed to support population-level analysis of emergency department utilization by mapping discharge diagnosis codes to probabilities that a visit falls into clinically meaningful ED-use categories.
This mart builds on core.encounter. It keeps all emergency department encounters and adds ED classification detail when the primary diagnosis code is included in the classification lookup.
Install this standalone package alongside Core using the data mart installation guide.
Methodology
The original NYU algorithm assigns probabilities rather than making a definitive visit-level judgment. A diagnosis can have probability weights across categories such as non-emergent, emergent primary-care treatable, emergent ED care needed and preventable, and emergent ED care needed and not preventable. Injury, mental health, alcohol, drug, and unclassified categories are handled separately.
The Tuva implementation uses the 2017 update to the NYU ED Classification Algorithm. The final summary table assigns a single resolved category to each classified encounter by selecting the category with the highest available classification probability. Encounters whose primary diagnosis code is not in the lookup are retained with null classification fields; the example queries label them "Not Classified". The summary publishes the resolved category, not a probability distribution or a clinical judgment about an individual visit.
The NYU Wagner algorithm background page provides the original methodology context.
Classification Categories
| Classification | Description |
|---|---|
alcohol | Alcohol related |
drug | Drug related, excluding alcohol |
emergent_ed_not_preventable | Emergent, ED care needed, not preventable or avoidable |
emergent_ed_preventable | Emergent, ED care needed, preventable or avoidable |
emergent_primary_care | Emergent, primary care treatable |
injury | Injury related |
mental_health | Mental health related |
non_emergent | Non-emergent |
unclassified | Not classified |
Outputs
| Model | Description |
|---|---|
ed_classification.summary | One row per emergency department encounter and data source with ED classification, diagnosis, facility, patient, and cost context. |
Example SQL
ED Visits by Classification
select
data_source
, coalesce(ed_classification_description, 'Not Classified') as ed_classification
, count(*) as ed_visit_count
, sum(cast(paid_amount as decimal(18, 2))) as paid_amount
, cast(avg(paid_amount) as decimal(18, 2)) as average_paid_amount
from ed_classification.summary
group by
data_source
, coalesce(ed_classification_description, 'Not Classified')
order by ed_visit_count desc;
Monthly ED Visit Trend
select
data_source
, year_month
, count(*) as ed_visit_count
, sum(cast(paid_amount as decimal(18, 2))) as paid_amount
, cast(avg(paid_amount) as decimal(18, 2)) as average_paid_amount
from ed_classification.summary
group by
data_source
, year_month
order by
data_source
, year_month;
ED Visits PKPY
with ed_visits as (
select
data_source
, year_month
, count(*) as ed_visit_count
from ed_classification.summary
group by
data_source
, year_month
)
, member_months as (
select
data_source
, year_month
, count(*) as member_month_count
from core.member_month
group by
data_source
, year_month
)
select
member_months.data_source
, member_months.year_month
, member_months.member_month_count
, coalesce(ed_visits.ed_visit_count, 0) as ed_visit_count
, cast(
coalesce(ed_visits.ed_visit_count, 0) * 12000.0
/ nullif(member_months.member_month_count, 0)
as decimal(18, 2)
) as ed_visits_pkpy
from member_months
left join ed_visits
on member_months.data_source = ed_visits.data_source
and member_months.year_month = ed_visits.year_month
order by
member_months.data_source
, member_months.year_month;
ED Visits by Facility
select
facility_npi
, facility_name
, facility_state
, count(*) as ed_visit_count
, sum(cast(paid_amount as decimal(18, 2))) as paid_amount
, cast(
sum(paid_amount) / nullif(count(*), 0)
as decimal(18, 2)
) as paid_per_visit
from ed_classification.summary
group by
facility_npi
, facility_name
, facility_state
order by ed_visit_count desc;
ED Visits by CCSR Diagnosis Category
with ccsr_encounter_category as (
select distinct
encounter_id
, data_source
, ccsr_category
, ccsr_category_description
, ccsr_parent_category
, body_system
from <target_schema>.ccsr__long_condition_category
where diagnosis_rank = 1
)
select
ccsr.ccsr_category
, ccsr.ccsr_category_description
, ccsr.ccsr_parent_category
, ccsr.body_system
, count(*) as ed_visit_count
, sum(cast(ed.paid_amount as decimal(18, 2))) as paid_amount
, cast(
sum(ed.paid_amount) / nullif(count(*), 0)
as decimal(18, 2)
) as paid_per_visit
from ed_classification.summary as ed
left join ccsr_encounter_category as ccsr
on ed.encounter_id = ccsr.encounter_id
and ed.data_source = ccsr.data_source
group by
ccsr.ccsr_category
, ccsr.ccsr_category_description
, ccsr.ccsr_parent_category
, ccsr.body_system
order by ed_visit_count desc;