1- -- Classify oxygen devices into six relevant clinical categories in ordinal fashion
2- -- Invasive oxygen delivery types:
3- -- Tracheostomy (with or without positive pressure ventilation)
4- -- InvasiveVent (positive pressure ventilation via endotracheal tube, could be oro/nasotracheal or tracheostomy)
5- -- Non invasive oxygen delivery types (divided similar to doi:10.1001/jama.2020.9524):
6- -- NonInvasiveVent (non-invasive positive pressure ventilation)
7- -- HFNC (high flow nasal oxygen / cannula)
8- -- SupplementalOxygen (all other non-rebreather, facemask, face tent, nasal prongs...)
9- -- No oxygen device:
10- -- None
1+ -- Classify oxygen devices and ventilator modes into six clinical categories.
2+
3+ -- Categories include..
4+ -- Invasive oxygen delivery types:
5+ -- Tracheostomy (with or without positive pressure ventilation)
6+ -- InvasiveVent (positive pressure ventilation via endotracheal tube, could be oro/nasotracheal or tracheostomy)
7+ -- Non invasive oxygen delivery types (divided similar to doi:10.1001/jama.2020.9524):
8+ -- NonInvasiveVent (non-invasive positive pressure ventilation)
9+ -- HFNC (high flow nasal oxygen / cannula)
10+ -- SupplementalOxygen (all other non-rebreather, facemask, face tent, nasal prongs...)
11+ -- No oxygen device:
12+ -- None
13+
14+ -- When conflicting settings occur (rare), the priority is:
15+ -- trach > mech vent > NIV > high flow > o2
16+
1117-- Some useful cases for debugging:
1218-- stay_id = 30019660 has a tracheostomy placed in the ICU
1319-- stay_id = 30000117 has explicit documentation of extubation
14- -- classify vent settings into modes
20+
21+ -- first we collect all times which have relevant documentation
1522WITH tm AS
1623(
1724 SELECT stay_id, charttime
@@ -34,11 +41,11 @@ WITH tm AS
3441 (
3542 ' Tracheostomy tube' ,
3643 ' Trach mask ' -- 16435 observations
37- -- 'T-piece', -- 1135 observations (T-piece could be either InvasiveVent or Tracheostomy)
44+ -- 'T-piece', -- 1135 observations (T-piece could be either InvasiveVent or Tracheostomy)
3845
3946 )
4047 THEN ' Tracheostomy'
41- -- mechanical ventilation
48+ -- mechanical / invasive ventilation
4249 WHEN o2_delivery_device_1 IN
4350 (
4451 ' Endotracheal tube'
@@ -110,7 +117,7 @@ WITH tm AS
110117 )
111118 THEN ' NonInvasiveVent'
112119 -- high flow nasal cannula
113- when o2_delivery_device_1 IN
120+ when o2_delivery_device_1 IN
114121 (
115122 ' High flow nasal cannula' -- 925 observations
116123 )
@@ -127,12 +134,14 @@ WITH tm AS
127134 ' Vapomist' , -- 3 observations
128135 ' Oxymizer' , -- 1301 observations
129136 ' High flow neb' , -- 10785 observations
130- ' Nasal cannula' )
131- then ' SupplementalOxygen'
137+ ' Nasal cannula'
138+ )
139+ THEN ' SupplementalOxygen'
132140 WHEN o2_delivery_device_1 in
133141 (
134- ' None' )
135- THEN ' None'
142+ ' None'
143+ )
144+ THEN ' None'
136145 -- not categorized: other
137146 ELSE NULL END AS ventilation_status
138147 FROM tm
@@ -148,8 +157,8 @@ WITH tm AS
148157 SELECT
149158 stay_id, charttime
150159 -- source data columns, here for debug
151- , o2_delivery_device_1
152- , vent_mode
160+ -- , o2_delivery_device_1
161+ -- , vent_mode
153162 -- carry over the previous charttime which had the same state
154163 , LAG(charttime, 1 ) OVER (PARTITION BY stay_id, ventilation_status ORDER BY charttime) AS charttime_lag
155164 -- bring back the next charttime, regardless of the state
@@ -165,34 +174,42 @@ WITH tm AS
165174(
166175 SELECT
167176 stay_id
168- -- source data columns, here for debug
169- , o2_delivery_device_1
170- , vent_mode
171- , charttime_lag
172177 , charttime
178+ , charttime_lag
173179 , charttime_lead
174180 , ventilation_status
175181
182+ -- source data columns, here for debug
183+ -- , o2_delivery_device_1
184+ -- , vent_mode
185+
176186 -- calculate the time since the last event
177187 , DATETIME_DIFF(charttime, charttime_lag, MINUTE)/ 60 as ventduration
178188
179189 -- now we determine if the current ventilation status is "new", or continuing the previous
180190 , CASE
191+ -- if lag is null, this is the first event for the patient
192+ WHEN ventilation_status_lag IS NULL THEN 1
181193 -- a 14 hour gap always initiates a new event
182194 WHEN DATETIME_DIFF(charttime, charttime_lag, HOUR) >= 14 THEN 1
183- WHEN ventilation_status_lag IS NULL THEN 1
184195 -- not a new event if identical to the last row
185196 WHEN ventilation_status_lag != ventilation_status THEN 1
186197 ELSE 0
187- END AS new_status
198+ END AS new_ventilation_event
188199 FROM vd0
189200)
190201, vd2 as
191202(
192- SELECT vd1.*
203+ SELECT vd1 .stay_id , vd1 .charttime
204+ , ventduration, new_ventilation_event
193205 -- create a cumulative sum of the instances of new ventilation
194- -- this results in a monotonic integer assigned to each instance of ventilation
195- , SUM (new_status) OVER (PARTITION BY stay_id ORDER BY charttime) AS vent_num
206+ -- this results in a monotonically increasing integer assigned
207+ -- to each instance of ventilation
208+ , SUM (new_ventilation_event) OVER
209+ (
210+ PARTITION BY stay_id
211+ ORDER BY charttime
212+ ) AS vent_seq
196213 FROM vd1
197214)
198215-- create the durations for each ventilation instance
@@ -210,9 +227,10 @@ SELECT stay_id
210227 END
211228 ) AS endtime
212229 -- all rows with the same vent_num will have the same ventilation_status
213- -- for efficiency, we use an aggregate here, but we could equally well group by this column
230+ -- for efficiency, we use an aggregate here,
231+ -- but we could equally well group by this column
214232 , MAX (ventilation_status) AS ventilation_status
215233FROM vd2
216- GROUP BY stay_id, vent_num
234+ GROUP BY stay_id, vent_seq
217235HAVING min (charttime) != max (charttime)
218236;
0 commit comments