Skip to content

Commit 316cb96

Browse files
committed
fix: rework uo rates to use more precise timing
1 parent 72df721 commit 316cb96

File tree

1 file changed

+87
-55
lines changed

1 file changed

+87
-55
lines changed

mimic-iv/concepts/organfailure/kdigo_uo.sql

Lines changed: 87 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,69 @@
1-
with ur_stg as
1+
WITH uo_stg1 AS
22
(
3-
select io.stay_id, io.charttime
4-
-- we have joined each row to all rows preceding within 24 hours
5-
-- we can now sum these rows to get total UO over the last 24 hours
6-
-- we can use case statements to restrict it to only the last 6/12 hours
7-
-- therefore we have three sums:
8-
-- 1) over a 6 hour period
9-
-- 2) over a 12 hour period
10-
-- 3) over a 24 hour period
11-
-- note that we assume data charted at charttime corresponds to 1 hour of UO
12-
-- therefore we use '5' and '11' to restrict the period, rather than 6/12
13-
-- this assumption may overestimate UO rate when documentation is done less than hourly
3+
SELECT ie.stay_id, uo.charttime
4+
, DATETIME_DIFF(charttime, intime, SECOND) AS seconds_since_admit
5+
, COALESCE(
6+
DATETIME_DIFF(charttime, LAG(charttime) OVER (PARTITION BY ie.stay_id ORDER BY charttime), SECOND)/3600.0,
7+
1
8+
) AS hours_since_previous_row
9+
, urineoutput
10+
FROM `physionet-data.mimiciv_icu.icustays` ie
11+
INNER JOIN `physionet-data.mimiciv_derived.urine_output` uo
12+
ON ie.stay_id = uo.stay_id
13+
)
14+
, uo_stg2 as
15+
(
16+
select stay_id, charttime
17+
, hours_since_previous_row
18+
, urineoutput
19+
-- Use the RANGE partition to limit the summation to the last X hours.
20+
-- RANGE operates using numeric, so we convert the charttime into seconds
21+
-- since admission, and then filter to X seconds prior to the current row.
22+
-- where X can be 21600 (6 hours), 43200 (12 hours), or 86400 (24 hours).
23+
, SUM(urineoutput) OVER
24+
(
25+
PARTITION BY stay_id
26+
ORDER BY seconds_since_admit
27+
RANGE BETWEEN 21600 PRECEDING AND CURRENT ROW
28+
) AS urineoutput_6hr
29+
30+
, SUM(urineoutput) OVER
31+
(
32+
PARTITION BY stay_id
33+
ORDER BY seconds_since_admit
34+
RANGE BETWEEN 43200 PRECEDING AND CURRENT ROW
35+
) AS urineoutput_12hr
36+
37+
, SUM(urineoutput) OVER
38+
(
39+
PARTITION BY stay_id
40+
ORDER BY seconds_since_admit
41+
RANGE BETWEEN 86400 PRECEDING AND CURRENT ROW
42+
) AS urineoutput_24hr
1443

15-
-- 6 hours
16-
, sum(case when iosum.charttime >= DATETIME_SUB(io.charttime, interval '5' hour)
17-
then iosum.urineoutput
18-
else null end) as UrineOutput_6hr
19-
-- 12 hours
20-
, sum(case when iosum.charttime >= DATETIME_SUB(io.charttime, interval '11' hour)
21-
then iosum.urineoutput
22-
else null end) as UrineOutput_12hr
23-
-- 24 hours
24-
, sum(iosum.urineoutput) as UrineOutput_24hr
25-
26-
-- calculate the number of hours over which we've tabulated UO
27-
, ROUND(CAST(
28-
DATETIME_DIFF(io.charttime,
29-
-- below MIN() gets the earliest time that was used in the summation
30-
MIN(case when iosum.charttime >= DATETIME_SUB(io.charttime, interval '5' hour)
31-
then iosum.charttime
32-
else null end),
33-
SECOND) AS NUMERIC)/3600.0, 4)
34-
AS uo_tm_6hr
35-
-- repeat extraction for 12 hours and 24 hours
36-
, ROUND(CAST(
37-
DATETIME_DIFF(io.charttime,
38-
MIN(case when iosum.charttime >= DATETIME_SUB(io.charttime, interval '11' hour)
39-
then iosum.charttime
40-
else null end),
41-
SECOND) AS NUMERIC)/3600.0, 4)
42-
AS uo_tm_12hr
43-
, ROUND(CAST(
44-
DATETIME_DIFF(io.charttime, MIN(iosum.charttime), SECOND)
45-
AS NUMERIC)/3600.0, 4) AS uo_tm_24hr
46-
from `physionet-data.mimiciv_derived.urine_output` io
47-
-- this join gives all UO measurements over the 24 hours preceding this row
48-
left join `physionet-data.mimiciv_derived.urine_output` iosum
49-
on io.stay_id = iosum.stay_id
50-
and iosum.charttime <= io.charttime
51-
and iosum.charttime >= DATETIME_SUB(io.charttime, interval '23' hour)
52-
group by io.stay_id, io.charttime
44+
-- repeat the summations using the hours_since_previous_row column
45+
-- this gives us the amount of time the UO was calculated over
46+
, SUM(hours_since_previous_row) OVER
47+
(
48+
PARTITION BY stay_id
49+
ORDER BY seconds_since_admit
50+
RANGE BETWEEN 21600 PRECEDING AND CURRENT ROW
51+
) AS uo_tm_6hr
52+
53+
, SUM(hours_since_previous_row) OVER
54+
(
55+
PARTITION BY stay_id
56+
ORDER BY seconds_since_admit
57+
RANGE BETWEEN 43200 PRECEDING AND CURRENT ROW
58+
) AS uo_tm_12hr
59+
60+
, SUM(hours_since_previous_row) OVER
61+
(
62+
PARTITION BY stay_id
63+
ORDER BY seconds_since_admit
64+
RANGE BETWEEN 86400 PRECEDING AND CURRENT ROW
65+
) AS uo_tm_24hr
66+
from uo_stg1
5367
)
5468
select
5569
ur.stay_id
@@ -58,15 +72,33 @@ select
5872
, ur.urineoutput_6hr
5973
, ur.urineoutput_12hr
6074
, ur.urineoutput_24hr
61-
-- calculate rates - adding 1 hour as we assume data charted at 10:00 corresponds to previous hour
62-
, ROUND(CAST((ur.UrineOutput_6hr/wd.weight/(uo_tm_6hr+1)) AS NUMERIC), 4) AS uo_rt_6hr
63-
, ROUND(CAST((ur.UrineOutput_12hr/wd.weight/(uo_tm_12hr+1)) AS NUMERIC), 4) AS uo_rt_12hr
64-
, ROUND(CAST((ur.UrineOutput_24hr/wd.weight/(uo_tm_24hr+1)) AS NUMERIC), 4) AS uo_rt_24hr
75+
76+
-- calculate rates
77+
-- we would like to improve the sensitivity of this calculation by:
78+
-- (1) requiring UO documentation over at least N/2 hours
79+
-- (2) excluding a rate if it was calculated over >>N hours
80+
-- this is to remove cases where we have a very short measurement
81+
-- (e.g. one UO measurement made for 1 hour determining the 6 hour rate)
82+
-- and remove cases where we have very sparse measurements
83+
-- (e.g. two UO measurements 12 hours apart used for the 6 hour rate calculation)
84+
, CASE
85+
WHEN uo_tm_6hr > 3 AND uo_tm_6hr < 9
86+
THEN ROUND(CAST((ur.urineoutput_6hr/wd.weight/uo_tm_6hr) AS NUMERIC), 4)
87+
ELSE NULL END AS uo_rt_6hr
88+
, CASE
89+
WHEN uo_tm_12hr > 6 AND uo_tm_12hr < 18
90+
THEN ROUND(CAST((ur.urineoutput_12hr/wd.weight/uo_tm_12hr) AS NUMERIC), 4)
91+
ELSE NULL END AS uo_rt_12hr
92+
, CASE
93+
WHEN uo_tm_24hr > 12 AND uo_tm_24hr < 36
94+
THEN ROUND(CAST((ur.urineoutput_24hr/wd.weight/uo_tm_24hr) AS NUMERIC), 4)
95+
ELSE NULL END AS uo_rt_24hr
96+
6597
-- number of hours between current UO time and earliest charted UO within the X hour window
6698
, uo_tm_6hr
6799
, uo_tm_12hr
68100
, uo_tm_24hr
69-
from ur_stg ur
101+
from uo_stg2 ur
70102
left join `physionet-data.mimiciv_derived.weight_durations` wd
71103
on ur.stay_id = wd.stay_id
72104
and ur.charttime >= wd.starttime

0 commit comments

Comments
 (0)