initial
This commit is contained in:
259
sql/durations/dobutamine_dose.sql
Normal file
259
sql/durations/dobutamine_dose.sql
Normal file
@@ -0,0 +1,259 @@
|
||||
-- THIS SCRIPT IS AUTOMATICALLY GENERATED. DO NOT EDIT IT DIRECTLY.
|
||||
DROP TABLE IF EXISTS dobutamine_dose; CREATE TABLE dobutamine_dose AS
|
||||
-- This query extracts dose+durations of dopamine administration
|
||||
|
||||
-- Get drug administration data from CareVue first
|
||||
with vasocv1 as
|
||||
(
|
||||
select
|
||||
icustay_id, charttime
|
||||
-- case statement determining whether the ITEMID is an instance of vasopressor usage
|
||||
, max(case when itemid in (30042,30306) then 1 else 0 end) as vaso -- dobutamine
|
||||
|
||||
-- the 'stopped' column indicates if a vasopressor has been disconnected
|
||||
, max(case when itemid in (30042,30306) and (stopped = 'Stopped' OR stopped like 'D/C%') then 1
|
||||
else 0 end) as vaso_stopped
|
||||
|
||||
, max(case when itemid in (30042,30306) and rate is not null then 1 else 0 end) as vaso_null
|
||||
, max(case when itemid in (30042,30306) then rate else null end) as vaso_rate
|
||||
, max(case when itemid in (30042,30306) then amount else null end) as vaso_amount
|
||||
|
||||
FROM inputevents_cv
|
||||
where itemid in (30042,30306) -- dobutamine
|
||||
group by icustay_id, charttime
|
||||
)
|
||||
, vasocv2 as
|
||||
(
|
||||
select v.*
|
||||
, sum(vaso_null) over (partition by icustay_id order by charttime) as vaso_partition
|
||||
from
|
||||
vasocv1 v
|
||||
)
|
||||
, vasocv3 as
|
||||
(
|
||||
select v.*
|
||||
, first_value(vaso_rate) over (partition by icustay_id, vaso_partition order by charttime) as vaso_prevrate_ifnull
|
||||
from
|
||||
vasocv2 v
|
||||
)
|
||||
, vasocv4 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, charttime
|
||||
-- , (CHARTTIME - (LAG(CHARTTIME, 1) OVER (partition by icustay_id, vaso order by charttime))) AS delta
|
||||
|
||||
, vaso
|
||||
, vaso_rate
|
||||
, vaso_amount
|
||||
, vaso_stopped
|
||||
, vaso_prevrate_ifnull
|
||||
|
||||
-- We define start time here
|
||||
, case
|
||||
when vaso = 0 then null
|
||||
|
||||
-- if this is the first instance of the vasoactive drug
|
||||
when vaso_rate > 0 and
|
||||
LAG(vaso_prevrate_ifnull,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso, vaso_null
|
||||
order by charttime
|
||||
)
|
||||
is null
|
||||
then 1
|
||||
|
||||
-- you often get a string of 0s
|
||||
-- we decide not to set these as 1, just because it makes vasonum sequential
|
||||
when vaso_rate = 0 and
|
||||
LAG(vaso_prevrate_ifnull,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso
|
||||
order by charttime
|
||||
)
|
||||
= 0
|
||||
then 0
|
||||
|
||||
-- sometimes you get a string of NULL, associated with 0 volumes
|
||||
-- same reason as before, we decide not to set these as 1
|
||||
-- vaso_prevrate_ifnull is equal to the previous value *iff* the current value is null
|
||||
when vaso_prevrate_ifnull = 0 and
|
||||
LAG(vaso_prevrate_ifnull,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso
|
||||
order by charttime
|
||||
)
|
||||
= 0
|
||||
then 0
|
||||
|
||||
-- If the last recorded rate was 0, newvaso = 1
|
||||
when LAG(vaso_prevrate_ifnull,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso
|
||||
order by charttime
|
||||
) = 0
|
||||
then 1
|
||||
|
||||
-- If the last recorded vaso was D/C'd, newvaso = 1
|
||||
when
|
||||
LAG(vaso_stopped,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso
|
||||
order by charttime
|
||||
)
|
||||
= 1 then 1
|
||||
|
||||
-- ** not sure if the below is needed
|
||||
--when (CHARTTIME - (LAG(CHARTTIME, 1) OVER (partition by icustay_id, vaso order by charttime))) > (interval '4 hours') then 1
|
||||
else null
|
||||
end as vaso_start
|
||||
|
||||
FROM
|
||||
vasocv3
|
||||
)
|
||||
-- propagate start/stop flags forward in time
|
||||
, vasocv5 as
|
||||
(
|
||||
select v.*
|
||||
, SUM(vaso_start) OVER (partition by icustay_id, vaso order by charttime) as vaso_first
|
||||
FROM
|
||||
vasocv4 v
|
||||
)
|
||||
, vasocv6 as
|
||||
(
|
||||
select v.*
|
||||
-- We define end time here
|
||||
, case
|
||||
when vaso = 0
|
||||
then null
|
||||
|
||||
-- If the recorded vaso was D/C'd, this is an end time
|
||||
when vaso_stopped = 1
|
||||
then vaso_first
|
||||
|
||||
-- If the rate is zero, this is the end time
|
||||
when vaso_rate = 0
|
||||
then vaso_first
|
||||
|
||||
-- the last row in the table is always a potential end time
|
||||
-- this captures patients who die/are discharged while on vasopressors
|
||||
-- in principle, this could add an extra end time for the vasopressor
|
||||
-- however, since we later group on vaso_start, any extra end times are ignored
|
||||
when LEAD(CHARTTIME,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso
|
||||
order by charttime
|
||||
) is null
|
||||
then vaso_first
|
||||
|
||||
else null
|
||||
end as vaso_stop
|
||||
from vasocv5 v
|
||||
)
|
||||
|
||||
-- -- if you want to look at the results of the table before grouping:
|
||||
-- select
|
||||
-- icustay_id, charttime, vaso, vaso_rate, vaso_amount
|
||||
-- , vaso_stopped
|
||||
-- , vaso_start
|
||||
-- , vaso_first
|
||||
-- , vaso_stop
|
||||
-- from vasocv6 order by icustay_id, charttime;
|
||||
|
||||
, vasocv7 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, charttime as starttime
|
||||
, lead(charttime) OVER (partition by icustay_id, vaso_first order by charttime) as endtime
|
||||
, vaso, vaso_rate, vaso_amount, vaso_stop, vaso_start, vaso_first
|
||||
from vasocv6
|
||||
where
|
||||
vaso_first is not null -- bogus data
|
||||
and
|
||||
vaso_first != 0 -- sometimes *only* a rate of 0 appears, i.e. the drug is never actually delivered
|
||||
and
|
||||
icustay_id is not null -- there are data for "floating" admissions, we don't worry about these
|
||||
)
|
||||
-- table of start/stop times for event
|
||||
, vasocv8 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, starttime, endtime
|
||||
, vaso, vaso_rate, vaso_amount, vaso_stop, vaso_start, vaso_first
|
||||
from vasocv7
|
||||
where endtime is not null
|
||||
and vaso_rate > 0
|
||||
and starttime != endtime
|
||||
)
|
||||
-- collapse these start/stop times down if the rate doesn't change
|
||||
, vasocv9 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, starttime, endtime
|
||||
, case
|
||||
when LAG(endtime) OVER (partition by icustay_id order by starttime, endtime) = starttime
|
||||
AND LAG(vaso_rate) OVER (partition by icustay_id order by starttime, endtime) = vaso_rate
|
||||
THEN 0
|
||||
else 1
|
||||
end as vaso_groups
|
||||
, vaso, vaso_rate, vaso_amount, vaso_stop, vaso_start, vaso_first
|
||||
from vasocv8
|
||||
where endtime is not null
|
||||
and vaso_rate > 0
|
||||
and starttime != endtime
|
||||
)
|
||||
, vasocv10 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, starttime, endtime
|
||||
, vaso_groups
|
||||
, SUM(vaso_groups) OVER (partition by icustay_id order by starttime, endtime) as vaso_groups_sum
|
||||
, vaso, vaso_rate, vaso_amount, vaso_stop, vaso_start, vaso_first
|
||||
from vasocv9
|
||||
)
|
||||
, vasocv as
|
||||
(
|
||||
select icustay_id
|
||||
, min(starttime) as starttime
|
||||
, max(endtime) as endtime
|
||||
, vaso_groups_sum
|
||||
, vaso_rate
|
||||
, sum(vaso_amount) as vaso_amount
|
||||
from vasocv10
|
||||
group by icustay_id, vaso_groups_sum, vaso_rate
|
||||
)
|
||||
-- now we extract the associated data for metavision patients
|
||||
, vasomv as
|
||||
(
|
||||
select
|
||||
icustay_id, linkorderid
|
||||
, rate as vaso_rate
|
||||
, amount as vaso_amount
|
||||
, starttime
|
||||
, endtime
|
||||
from inputevents_mv
|
||||
where itemid = 221653 -- dobutamine
|
||||
and statusdescription != 'Rewritten' -- only valid orders
|
||||
)
|
||||
-- now assign this data to every hour of the patient's stay
|
||||
-- vaso_amount for carevue is not accurate
|
||||
SELECT icustay_id
|
||||
, starttime, endtime
|
||||
, vaso_rate, vaso_amount
|
||||
from vasocv
|
||||
UNION ALL
|
||||
SELECT icustay_id
|
||||
, starttime, endtime
|
||||
, vaso_rate, vaso_amount
|
||||
from vasomv
|
||||
order by icustay_id, starttime;
|
||||
262
sql/durations/dopamine_dose.sql
Normal file
262
sql/durations/dopamine_dose.sql
Normal file
@@ -0,0 +1,262 @@
|
||||
-- THIS SCRIPT IS AUTOMATICALLY GENERATED. DO NOT EDIT IT DIRECTLY.
|
||||
DROP TABLE IF EXISTS dopamine_dose; CREATE TABLE dopamine_dose AS
|
||||
-- This query extracts dose+durations of dopamine administration
|
||||
|
||||
-- Get drug administration data from CareVue first
|
||||
with vasocv1 as
|
||||
(
|
||||
select
|
||||
icustay_id, charttime
|
||||
-- case statement determining whether the ITEMID is an instance of vasopressor usage
|
||||
, max(case when itemid in (30043,30307) then 1 else 0 end) as vaso -- dopamine
|
||||
|
||||
-- the 'stopped' column indicates if a vasopressor has been disconnected
|
||||
, max(case when itemid in (30043,30307) and (stopped = 'Stopped' OR stopped like 'D/C%') then 1
|
||||
else 0 end) as vaso_stopped
|
||||
|
||||
, max(case when itemid in (30043,30307) and rate is not null then 1 else 0 end) as vaso_null
|
||||
, max(case when itemid in (30043,30307) then rate else null end) as vaso_rate
|
||||
, max(case when itemid in (30043,30307) then amount else null end) as vaso_amount
|
||||
|
||||
FROM inputevents_cv
|
||||
where itemid in
|
||||
(
|
||||
30043,30307 -- dopamine
|
||||
)
|
||||
group by icustay_id, charttime
|
||||
)
|
||||
, vasocv2 as
|
||||
(
|
||||
select v.*
|
||||
, sum(vaso_null) over (partition by icustay_id order by charttime) as vaso_partition
|
||||
from
|
||||
vasocv1 v
|
||||
)
|
||||
, vasocv3 as
|
||||
(
|
||||
select v.*
|
||||
, first_value(vaso_rate) over (partition by icustay_id, vaso_partition order by charttime) as vaso_prevrate_ifnull
|
||||
from
|
||||
vasocv2 v
|
||||
)
|
||||
, vasocv4 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, charttime
|
||||
-- , (CHARTTIME - (LAG(CHARTTIME, 1) OVER (partition by icustay_id, vaso order by charttime))) AS delta
|
||||
|
||||
, vaso
|
||||
, vaso_rate
|
||||
, vaso_amount
|
||||
, vaso_stopped
|
||||
, vaso_prevrate_ifnull
|
||||
|
||||
-- We define start time here
|
||||
, case
|
||||
when vaso = 0 then null
|
||||
|
||||
-- if this is the first instance of the vasoactive drug
|
||||
when vaso_rate > 0 and
|
||||
LAG(vaso_prevrate_ifnull,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso, vaso_null
|
||||
order by charttime
|
||||
)
|
||||
is null
|
||||
then 1
|
||||
|
||||
-- you often get a string of 0s
|
||||
-- we decide not to set these as 1, just because it makes vasonum sequential
|
||||
when vaso_rate = 0 and
|
||||
LAG(vaso_prevrate_ifnull,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso
|
||||
order by charttime
|
||||
)
|
||||
= 0
|
||||
then 0
|
||||
|
||||
-- sometimes you get a string of NULL, associated with 0 volumes
|
||||
-- same reason as before, we decide not to set these as 1
|
||||
-- vaso_prevrate_ifnull is equal to the previous value *iff* the current value is null
|
||||
when vaso_prevrate_ifnull = 0 and
|
||||
LAG(vaso_prevrate_ifnull,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso
|
||||
order by charttime
|
||||
)
|
||||
= 0
|
||||
then 0
|
||||
|
||||
-- If the last recorded rate was 0, newvaso = 1
|
||||
when LAG(vaso_prevrate_ifnull,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso
|
||||
order by charttime
|
||||
) = 0
|
||||
then 1
|
||||
|
||||
-- If the last recorded vaso was D/C'd, newvaso = 1
|
||||
when
|
||||
LAG(vaso_stopped,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso
|
||||
order by charttime
|
||||
)
|
||||
= 1 then 1
|
||||
|
||||
-- ** not sure if the below is needed
|
||||
--when (CHARTTIME - (LAG(CHARTTIME, 1) OVER (partition by icustay_id, vaso order by charttime))) > (interval '4 hours') then 1
|
||||
else null
|
||||
end as vaso_start
|
||||
|
||||
FROM
|
||||
vasocv3
|
||||
)
|
||||
-- propagate start/stop flags forward in time
|
||||
, vasocv5 as
|
||||
(
|
||||
select v.*
|
||||
, SUM(vaso_start) OVER (partition by icustay_id, vaso order by charttime) as vaso_first
|
||||
FROM
|
||||
vasocv4 v
|
||||
)
|
||||
, vasocv6 as
|
||||
(
|
||||
select v.*
|
||||
-- We define end time here
|
||||
, case
|
||||
when vaso = 0
|
||||
then null
|
||||
|
||||
-- If the recorded vaso was D/C'd, this is an end time
|
||||
when vaso_stopped = 1
|
||||
then vaso_first
|
||||
|
||||
-- If the rate is zero, this is the end time
|
||||
when vaso_rate = 0
|
||||
then vaso_first
|
||||
|
||||
-- the last row in the table is always a potential end time
|
||||
-- this captures patients who die/are discharged while on vasopressors
|
||||
-- in principle, this could add an extra end time for the vasopressor
|
||||
-- however, since we later group on vaso_start, any extra end times are ignored
|
||||
when LEAD(CHARTTIME,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso
|
||||
order by charttime
|
||||
) is null
|
||||
then vaso_first
|
||||
|
||||
else null
|
||||
end as vaso_stop
|
||||
from vasocv5 v
|
||||
)
|
||||
|
||||
-- -- if you want to look at the results of the table before grouping:
|
||||
-- select
|
||||
-- icustay_id, charttime, vaso, vaso_rate, vaso_amount
|
||||
-- , vaso_stopped
|
||||
-- , vaso_start
|
||||
-- , vaso_first
|
||||
-- , vaso_stop
|
||||
-- from vasocv6 order by icustay_id, charttime;
|
||||
|
||||
, vasocv7 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, charttime as starttime
|
||||
, lead(charttime) OVER (partition by icustay_id, vaso_first order by charttime) as endtime
|
||||
, vaso, vaso_rate, vaso_amount, vaso_stop, vaso_start, vaso_first
|
||||
from vasocv6
|
||||
where
|
||||
vaso_first is not null -- bogus data
|
||||
and
|
||||
vaso_first != 0 -- sometimes *only* a rate of 0 appears, i.e. the drug is never actually delivered
|
||||
and
|
||||
icustay_id is not null -- there are data for "floating" admissions, we don't worry about these
|
||||
)
|
||||
-- table of start/stop times for event
|
||||
, vasocv8 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, starttime, endtime
|
||||
, vaso, vaso_rate, vaso_amount, vaso_stop, vaso_start, vaso_first
|
||||
from vasocv7
|
||||
where endtime is not null
|
||||
and vaso_rate > 0
|
||||
and starttime != endtime
|
||||
)
|
||||
-- collapse these start/stop times down if the rate doesn't change
|
||||
, vasocv9 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, starttime, endtime
|
||||
, case
|
||||
when LAG(endtime) OVER (partition by icustay_id order by starttime, endtime) = starttime
|
||||
AND LAG(vaso_rate) OVER (partition by icustay_id order by starttime, endtime) = vaso_rate
|
||||
THEN 0
|
||||
else 1
|
||||
end as vaso_groups
|
||||
, vaso, vaso_rate, vaso_amount, vaso_stop, vaso_start, vaso_first
|
||||
from vasocv8
|
||||
where endtime is not null
|
||||
and vaso_rate > 0
|
||||
and starttime != endtime
|
||||
)
|
||||
, vasocv10 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, starttime, endtime
|
||||
, vaso_groups
|
||||
, SUM(vaso_groups) OVER (partition by icustay_id order by starttime, endtime) as vaso_groups_sum
|
||||
, vaso, vaso_rate, vaso_amount, vaso_stop, vaso_start, vaso_first
|
||||
from vasocv9
|
||||
)
|
||||
, vasocv as
|
||||
(
|
||||
select icustay_id
|
||||
, min(starttime) as starttime
|
||||
, max(endtime) as endtime
|
||||
, vaso_groups_sum
|
||||
, vaso_rate
|
||||
, sum(vaso_amount) as vaso_amount
|
||||
from vasocv10
|
||||
group by icustay_id, vaso_groups_sum, vaso_rate
|
||||
)
|
||||
-- now we extract the associated data for metavision patients
|
||||
, vasomv as
|
||||
(
|
||||
select
|
||||
icustay_id, linkorderid
|
||||
, rate as vaso_rate
|
||||
, amount as vaso_amount
|
||||
, starttime
|
||||
, endtime
|
||||
from inputevents_mv
|
||||
where itemid = 221662 -- dopamine
|
||||
and statusdescription != 'Rewritten' -- only valid orders
|
||||
)
|
||||
-- now assign this data to every hour of the patient's stay
|
||||
-- vaso_amount for carevue is not accurate
|
||||
SELECT icustay_id
|
||||
, starttime, endtime
|
||||
, vaso_rate, vaso_amount
|
||||
from vasocv
|
||||
UNION ALL
|
||||
SELECT icustay_id
|
||||
, starttime, endtime
|
||||
, vaso_rate, vaso_amount
|
||||
from vasomv
|
||||
order by icustay_id, starttime;
|
||||
273
sql/durations/epinephrine_dose.sql
Normal file
273
sql/durations/epinephrine_dose.sql
Normal file
@@ -0,0 +1,273 @@
|
||||
-- THIS SCRIPT IS AUTOMATICALLY GENERATED. DO NOT EDIT IT DIRECTLY.
|
||||
DROP TABLE IF EXISTS epinephrine_dose; CREATE TABLE epinephrine_dose AS
|
||||
-- This query extracts dose+durations of epinephrine administration
|
||||
|
||||
-- Requires the weightfirstday table
|
||||
|
||||
-- Get drug administration data from CareVue first
|
||||
with vasocv1 as
|
||||
(
|
||||
select
|
||||
cv.icustay_id, cv.charttime
|
||||
-- case statement determining whether the ITEMID is an instance of vasopressor usage
|
||||
, max(case when itemid in (30044,30119,30309) then 1 else 0 end) as vaso -- epinephrine
|
||||
|
||||
-- the 'stopped' column indicates if a vasopressor has been disconnected
|
||||
, max(case when itemid in (30044,30119,30309) and (stopped = 'Stopped' OR stopped like 'D/C%') then 1
|
||||
else 0 end) as vaso_stopped
|
||||
|
||||
, max(case when itemid in (30044,30119,30309) and rate is not null then 1 else 0 end) as vaso_null
|
||||
, max(case
|
||||
when itemid = 30044 and wd.weight is null then rate / 80.0 -- super rare to be missing weight... affects 2 patients for 14 rows
|
||||
when itemid = 30044 then rate / wd.weight -- measured in mcgmin
|
||||
when itemid in (30119,30309) then rate -- measured in mcgkgmin
|
||||
else null
|
||||
end) as vaso_rate
|
||||
, max(case when itemid in (30044,30119,30309) then amount else null end) as vaso_amount
|
||||
|
||||
FROM inputevents_cv cv
|
||||
left join weight_durations wd
|
||||
on cv.icustay_id = wd.icustay_id
|
||||
and cv.charttime between wd.starttime and wd.endtime
|
||||
where itemid in
|
||||
(
|
||||
30044,30119,30309 -- epinephrine
|
||||
)
|
||||
and cv.icustay_id is not null
|
||||
group by cv.icustay_id, charttime
|
||||
)
|
||||
, vasocv2 as
|
||||
(
|
||||
select v.*
|
||||
, sum(vaso_null) over (partition by icustay_id order by charttime) as vaso_partition
|
||||
from
|
||||
vasocv1 v
|
||||
)
|
||||
, vasocv3 as
|
||||
(
|
||||
select v.*
|
||||
, first_value(vaso_rate) over (partition by icustay_id, vaso_partition order by charttime) as vaso_prevrate_ifnull
|
||||
from
|
||||
vasocv2 v
|
||||
)
|
||||
, vasocv4 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, charttime
|
||||
-- , (CHARTTIME - (LAG(CHARTTIME, 1) OVER (partition by icustay_id, vaso order by charttime))) AS delta
|
||||
|
||||
, vaso
|
||||
, vaso_rate
|
||||
, vaso_amount
|
||||
, vaso_stopped
|
||||
, vaso_prevrate_ifnull
|
||||
|
||||
-- We define start time here
|
||||
, case
|
||||
when vaso = 0 then null
|
||||
|
||||
-- if this is the first instance of the vasoactive drug
|
||||
when vaso_rate > 0 and
|
||||
LAG(vaso_prevrate_ifnull,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso, vaso_null
|
||||
order by charttime
|
||||
)
|
||||
is null
|
||||
then 1
|
||||
|
||||
-- you often get a string of 0s
|
||||
-- we decide not to set these as 1, just because it makes vasonum sequential
|
||||
when vaso_rate = 0 and
|
||||
LAG(vaso_prevrate_ifnull,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso
|
||||
order by charttime
|
||||
)
|
||||
= 0
|
||||
then 0
|
||||
|
||||
-- sometimes you get a string of NULL, associated with 0 volumes
|
||||
-- same reason as before, we decide not to set these as 1
|
||||
-- vaso_prevrate_ifnull is equal to the previous value *iff* the current value is null
|
||||
when vaso_prevrate_ifnull = 0 and
|
||||
LAG(vaso_prevrate_ifnull,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso
|
||||
order by charttime
|
||||
)
|
||||
= 0
|
||||
then 0
|
||||
|
||||
-- If the last recorded rate was 0, newvaso = 1
|
||||
when LAG(vaso_prevrate_ifnull,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso
|
||||
order by charttime
|
||||
) = 0
|
||||
then 1
|
||||
|
||||
-- If the last recorded vaso was D/C'd, newvaso = 1
|
||||
when
|
||||
LAG(vaso_stopped,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso
|
||||
order by charttime
|
||||
)
|
||||
= 1 then 1
|
||||
|
||||
-- ** not sure if the below is needed
|
||||
--when (CHARTTIME - (LAG(CHARTTIME, 1) OVER (partition by icustay_id, vaso order by charttime))) > (interval '4 hours') then 1
|
||||
else null
|
||||
end as vaso_start
|
||||
|
||||
FROM
|
||||
vasocv3
|
||||
)
|
||||
-- propagate start/stop flags forward in time
|
||||
, vasocv5 as
|
||||
(
|
||||
select v.*
|
||||
, SUM(vaso_start) OVER (partition by icustay_id, vaso order by charttime) as vaso_first
|
||||
FROM
|
||||
vasocv4 v
|
||||
)
|
||||
, vasocv6 as
|
||||
(
|
||||
select v.*
|
||||
-- We define end time here
|
||||
, case
|
||||
when vaso = 0
|
||||
then null
|
||||
|
||||
-- If the recorded vaso was D/C'd, this is an end time
|
||||
when vaso_stopped = 1
|
||||
then vaso_first
|
||||
|
||||
-- If the rate is zero, this is the end time
|
||||
when vaso_rate = 0
|
||||
then vaso_first
|
||||
|
||||
-- the last row in the table is always a potential end time
|
||||
-- this captures patients who die/are discharged while on vasopressors
|
||||
-- in principle, this could add an extra end time for the vasopressor
|
||||
-- however, since we later group on vaso_start, any extra end times are ignored
|
||||
when LEAD(CHARTTIME,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso
|
||||
order by charttime
|
||||
) is null
|
||||
then vaso_first
|
||||
|
||||
else null
|
||||
end as vaso_stop
|
||||
from vasocv5 v
|
||||
)
|
||||
|
||||
-- -- if you want to look at the results of the table before grouping:
|
||||
-- select
|
||||
-- icustay_id, charttime, vaso, vaso_rate, vaso_amount
|
||||
-- , vaso_stopped
|
||||
-- , vaso_start
|
||||
-- , vaso_first
|
||||
-- , vaso_stop
|
||||
-- from vasocv6 order by icustay_id, charttime;
|
||||
|
||||
, vasocv7 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, charttime as starttime
|
||||
, lead(charttime) OVER (partition by icustay_id, vaso_first order by charttime) as endtime
|
||||
, vaso, vaso_rate, vaso_amount, vaso_stop, vaso_start, vaso_first
|
||||
from vasocv6
|
||||
where
|
||||
vaso_first is not null -- bogus data
|
||||
and
|
||||
vaso_first != 0 -- sometimes *only* a rate of 0 appears, i.e. the drug is never actually delivered
|
||||
and
|
||||
icustay_id is not null -- there are data for "floating" admissions, we don't worry about these
|
||||
)
|
||||
-- table of start/stop times for event
|
||||
, vasocv8 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, starttime, endtime
|
||||
, vaso, vaso_rate, vaso_amount, vaso_stop, vaso_start, vaso_first
|
||||
from vasocv7
|
||||
where endtime is not null
|
||||
and vaso_rate > 0
|
||||
and starttime != endtime
|
||||
)
|
||||
-- collapse these start/stop times down if the rate doesn't change
|
||||
, vasocv9 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, starttime, endtime
|
||||
, case
|
||||
when LAG(endtime) OVER (partition by icustay_id order by starttime, endtime) = starttime
|
||||
AND LAG(vaso_rate) OVER (partition by icustay_id order by starttime, endtime) = vaso_rate
|
||||
THEN 0
|
||||
else 1
|
||||
end as vaso_groups
|
||||
, vaso, vaso_rate, vaso_amount, vaso_stop, vaso_start, vaso_first
|
||||
from vasocv8
|
||||
where endtime is not null
|
||||
and vaso_rate > 0
|
||||
and starttime != endtime
|
||||
)
|
||||
, vasocv10 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, starttime, endtime
|
||||
, vaso_groups
|
||||
, SUM(vaso_groups) OVER (partition by icustay_id order by starttime, endtime) as vaso_groups_sum
|
||||
, vaso, vaso_rate, vaso_amount, vaso_stop, vaso_start, vaso_first
|
||||
from vasocv9
|
||||
)
|
||||
, vasocv as
|
||||
(
|
||||
select icustay_id
|
||||
, min(starttime) as starttime
|
||||
, max(endtime) as endtime
|
||||
, vaso_groups_sum
|
||||
, vaso_rate
|
||||
, sum(vaso_amount) as vaso_amount
|
||||
from vasocv10
|
||||
group by icustay_id, vaso_groups_sum, vaso_rate
|
||||
)
|
||||
-- now we extract the associated data for metavision patients
|
||||
, vasomv as
|
||||
(
|
||||
select
|
||||
icustay_id, linkorderid
|
||||
, rate as vaso_rate
|
||||
, amount as vaso_amount
|
||||
, starttime
|
||||
, endtime
|
||||
from inputevents_mv
|
||||
where itemid = 221289 -- epinephrine
|
||||
and statusdescription != 'Rewritten' -- only valid orders
|
||||
)
|
||||
-- now assign this data to every hour of the patient's stay
|
||||
-- vaso_amount for carevue is not accurate
|
||||
SELECT icustay_id
|
||||
, starttime, endtime
|
||||
, vaso_rate, vaso_amount
|
||||
from vasocv
|
||||
UNION ALL
|
||||
SELECT icustay_id
|
||||
, starttime, endtime
|
||||
, vaso_rate, vaso_amount
|
||||
from vasomv
|
||||
order by icustay_id, starttime;
|
||||
270
sql/durations/norepinephrine_dose.sql
Normal file
270
sql/durations/norepinephrine_dose.sql
Normal file
@@ -0,0 +1,270 @@
|
||||
-- THIS SCRIPT IS AUTOMATICALLY GENERATED. DO NOT EDIT IT DIRECTLY.
|
||||
DROP TABLE IF EXISTS norepinephrine_dose; CREATE TABLE norepinephrine_dose AS
|
||||
-- This query extracts dose+durations of norepinephrine administration
|
||||
-- Total time on the drug can be calculated from this table by grouping using ICUSTAY_ID
|
||||
|
||||
-- Get drug administration data from CareVue first
|
||||
with vasocv1 as
|
||||
(
|
||||
select
|
||||
cv.icustay_id, cv.charttime
|
||||
-- case statement determining whether the ITEMID is an instance of vasopressor usage
|
||||
, max(case when itemid in (30047,30120) then 1 else 0 end) as vaso -- norepinephrine
|
||||
|
||||
-- the 'stopped' column indicates if a vasopressor has been disconnected
|
||||
, max(case when itemid in (30047,30120) and (stopped = 'Stopped' OR stopped like 'D/C%') then 1
|
||||
else 0 end) as vaso_stopped
|
||||
|
||||
-- case statement determining whether the ITEMID is an instance of vasopressor usage
|
||||
|
||||
, max(case when itemid in (30047,30120) and rate is not null then 1 else 0 end) as vaso_null
|
||||
, max(case
|
||||
when itemid = 30047 and wd.weight is null then rate / 80.0 -- this is rare, only affects a total of ~400 rows
|
||||
when itemid = 30047 then rate / wd.weight -- measured in mcgmin
|
||||
when itemid = 30120 then rate -- measured in mcgkgmin ** there are clear errors, perhaps actually mcgmin
|
||||
else null end) as vaso_rate
|
||||
, max(case when itemid in (30047,30120) then amount else null end) as vaso_amount
|
||||
|
||||
FROM inputevents_cv cv
|
||||
left join weight_durations wd
|
||||
on cv.icustay_id = wd.icustay_id
|
||||
and cv.charttime between wd.starttime and wd.endtime
|
||||
where itemid in (30047,30120) -- norepinephrine
|
||||
and cv.icustay_id is not null
|
||||
group by cv.icustay_id, cv.charttime
|
||||
)
|
||||
, vasocv2 as
|
||||
(
|
||||
select v.*
|
||||
, sum(vaso_null) over (partition by icustay_id order by charttime) as vaso_partition
|
||||
from
|
||||
vasocv1 v
|
||||
)
|
||||
, vasocv3 as
|
||||
(
|
||||
select v.*
|
||||
, first_value(vaso_rate) over (partition by icustay_id, vaso_partition order by charttime) as vaso_prevrate_ifnull
|
||||
from
|
||||
vasocv2 v
|
||||
)
|
||||
, vasocv4 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, charttime
|
||||
-- , (CHARTTIME - (LAG(CHARTTIME, 1) OVER (partition by icustay_id, vaso order by charttime))) AS delta
|
||||
|
||||
, vaso
|
||||
, vaso_rate
|
||||
, vaso_amount
|
||||
, vaso_stopped
|
||||
, vaso_prevrate_ifnull
|
||||
|
||||
-- We define start time here
|
||||
, case
|
||||
when vaso = 0 then null
|
||||
|
||||
-- if this is the first instance of the vasoactive drug
|
||||
when vaso_rate > 0 and
|
||||
LAG(vaso_prevrate_ifnull,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso, vaso_null
|
||||
order by charttime
|
||||
)
|
||||
is null
|
||||
then 1
|
||||
|
||||
-- you often get a string of 0s
|
||||
-- we decide not to set these as 1, just because it makes vasonum sequential
|
||||
when vaso_rate = 0 and
|
||||
LAG(vaso_prevrate_ifnull,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso
|
||||
order by charttime
|
||||
)
|
||||
= 0
|
||||
then 0
|
||||
|
||||
-- sometimes you get a string of NULL, associated with 0 volumes
|
||||
-- same reason as before, we decide not to set these as 1
|
||||
-- vaso_prevrate_ifnull is equal to the previous value *iff* the current value is null
|
||||
when vaso_prevrate_ifnull = 0 and
|
||||
LAG(vaso_prevrate_ifnull,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso
|
||||
order by charttime
|
||||
)
|
||||
= 0
|
||||
then 0
|
||||
|
||||
-- If the last recorded rate was 0, newvaso = 1
|
||||
when LAG(vaso_prevrate_ifnull,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso
|
||||
order by charttime
|
||||
) = 0
|
||||
then 1
|
||||
|
||||
-- If the last recorded vaso was D/C'd, newvaso = 1
|
||||
when
|
||||
LAG(vaso_stopped,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso
|
||||
order by charttime
|
||||
)
|
||||
= 1 then 1
|
||||
|
||||
-- ** not sure if the below is needed
|
||||
--when (CHARTTIME - (LAG(CHARTTIME, 1) OVER (partition by icustay_id, vaso order by charttime))) > (interval '4 hours') then 1
|
||||
else null
|
||||
end as vaso_start
|
||||
|
||||
FROM
|
||||
vasocv3
|
||||
)
|
||||
-- propagate start/stop flags forward in time
|
||||
, vasocv5 as
|
||||
(
|
||||
select v.*
|
||||
, SUM(vaso_start) OVER (partition by icustay_id, vaso order by charttime) as vaso_first
|
||||
FROM
|
||||
vasocv4 v
|
||||
)
|
||||
, vasocv6 as
|
||||
(
|
||||
select v.*
|
||||
-- We define end time here
|
||||
, case
|
||||
when vaso = 0
|
||||
then null
|
||||
|
||||
-- If the recorded vaso was D/C'd, this is an end time
|
||||
when vaso_stopped = 1
|
||||
then vaso_first
|
||||
|
||||
-- If the rate is zero, this is the end time
|
||||
when vaso_rate = 0
|
||||
then vaso_first
|
||||
|
||||
-- the last row in the table is always a potential end time
|
||||
-- this captures patients who die/are discharged while on vasopressors
|
||||
-- in principle, this could add an extra end time for the vasopressor
|
||||
-- however, since we later group on vaso_start, any extra end times are ignored
|
||||
when LEAD(CHARTTIME,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, vaso
|
||||
order by charttime
|
||||
) is null
|
||||
then vaso_first
|
||||
|
||||
else null
|
||||
end as vaso_stop
|
||||
from vasocv5 v
|
||||
)
|
||||
|
||||
-- -- if you want to look at the results of the table before grouping:
|
||||
-- select
|
||||
-- icustay_id, charttime, vaso, vaso_rate, vaso_amount
|
||||
-- , vaso_stopped
|
||||
-- , vaso_start
|
||||
-- , vaso_first
|
||||
-- , vaso_stop
|
||||
-- from vasocv6 order by icustay_id, charttime;
|
||||
|
||||
, vasocv7 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, charttime as starttime
|
||||
, lead(charttime) OVER (partition by icustay_id, vaso_first order by charttime) as endtime
|
||||
, vaso, vaso_rate, vaso_amount, vaso_stop, vaso_start, vaso_first
|
||||
from vasocv6
|
||||
where
|
||||
vaso_first is not null -- bogus data
|
||||
and
|
||||
vaso_first != 0 -- sometimes *only* a rate of 0 appears, i.e. the drug is never actually delivered
|
||||
and
|
||||
icustay_id is not null -- there are data for "floating" admissions, we don't worry about these
|
||||
)
|
||||
-- table of start/stop times for event
|
||||
, vasocv8 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, starttime, endtime
|
||||
, vaso, vaso_rate, vaso_amount, vaso_stop, vaso_start, vaso_first
|
||||
from vasocv7
|
||||
where endtime is not null
|
||||
and vaso_rate > 0
|
||||
and starttime != endtime
|
||||
)
|
||||
-- collapse these start/stop times down if the rate doesn't change
|
||||
, vasocv9 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, starttime, endtime
|
||||
, case
|
||||
when LAG(endtime) OVER (partition by icustay_id order by starttime, endtime) = starttime
|
||||
AND LAG(vaso_rate) OVER (partition by icustay_id order by starttime, endtime) = vaso_rate
|
||||
THEN 0
|
||||
else 1
|
||||
end as vaso_groups
|
||||
, vaso, vaso_rate, vaso_amount, vaso_stop, vaso_start, vaso_first
|
||||
from vasocv8
|
||||
where endtime is not null
|
||||
and vaso_rate > 0
|
||||
and starttime != endtime
|
||||
)
|
||||
, vasocv10 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, starttime, endtime
|
||||
, vaso_groups
|
||||
, SUM(vaso_groups) OVER (partition by icustay_id order by starttime, endtime) as vaso_groups_sum
|
||||
, vaso, vaso_rate, vaso_amount, vaso_stop, vaso_start, vaso_first
|
||||
from vasocv9
|
||||
)
|
||||
, vasocv as
|
||||
(
|
||||
select icustay_id
|
||||
, min(starttime) as starttime
|
||||
, max(endtime) as endtime
|
||||
, vaso_groups_sum
|
||||
, vaso_rate
|
||||
, sum(vaso_amount) as vaso_amount
|
||||
from vasocv10
|
||||
group by icustay_id, vaso_groups_sum, vaso_rate
|
||||
)
|
||||
-- now we extract the associated data for metavision patients
|
||||
, vasomv as
|
||||
(
|
||||
select
|
||||
icustay_id, linkorderid
|
||||
, rate as vaso_rate
|
||||
, amount as vaso_amount
|
||||
, starttime
|
||||
, endtime
|
||||
from inputevents_mv
|
||||
where itemid = 221906 -- norepinephrine
|
||||
and statusdescription != 'Rewritten' -- only valid orders
|
||||
)
|
||||
-- now assign this data to every hour of the patient's stay
|
||||
-- vaso_amount for carevue is not accurate
|
||||
SELECT icustay_id
|
||||
, starttime, endtime
|
||||
, vaso_rate, vaso_amount
|
||||
from vasocv
|
||||
UNION ALL
|
||||
SELECT icustay_id
|
||||
, starttime, endtime
|
||||
, vaso_rate, vaso_amount
|
||||
from vasomv
|
||||
order by icustay_id, starttime;
|
||||
142
sql/durations/ventilation_classification.sql
Normal file
142
sql/durations/ventilation_classification.sql
Normal file
@@ -0,0 +1,142 @@
|
||||
-- THIS SCRIPT IS AUTOMATICALLY GENERATED. DO NOT EDIT IT DIRECTLY.
|
||||
DROP TABLE IF EXISTS ventilation_classification; CREATE TABLE ventilation_classification AS
|
||||
-- Identify The presence of a mechanical ventilation using settings
|
||||
select
|
||||
icustay_id, charttime
|
||||
-- case statement determining whether it is an instance of mech vent
|
||||
, max(
|
||||
case
|
||||
when itemid is null or value is null then 0 -- can't have null values
|
||||
when itemid = 720 and value != 'Other/Remarks' THEN 1 -- VentTypeRecorded
|
||||
when itemid = 223848 and value != 'Other' THEN 1
|
||||
when itemid = 223849 then 1 -- ventilator mode
|
||||
when itemid = 467 and value = 'Ventilator' THEN 1 -- O2 delivery device == ventilator
|
||||
when itemid in
|
||||
(
|
||||
445, 448, 449, 450, 1340, 1486, 1600, 224687 -- minute volume
|
||||
, 639, 654, 681, 682, 683, 684,224685,224684,224686 -- tidal volume
|
||||
, 218,436,535,444,459,224697,224695,224696,224746,224747 -- High/Low/Peak/Mean/Neg insp force ("RespPressure")
|
||||
, 221,1,1211,1655,2000,226873,224738,224419,224750,227187 -- Insp pressure
|
||||
, 543 -- PlateauPressure
|
||||
, 5865,5866,224707,224709,224705,224706 -- APRV pressure
|
||||
, 60,437,505,506,686,220339,224700 -- PEEP
|
||||
, 3459 -- high pressure relief
|
||||
, 501,502,503,224702 -- PCV
|
||||
, 223,667,668,669,670,671,672 -- TCPCV
|
||||
, 224701 -- PSVlevel
|
||||
)
|
||||
THEN 1
|
||||
else 0
|
||||
end
|
||||
) as MechVent
|
||||
, max(
|
||||
case
|
||||
-- initiation of oxygen therapy indicates the ventilation has ended
|
||||
when itemid = 226732 and value in
|
||||
(
|
||||
'Nasal cannula', -- 153714 observations
|
||||
'Face tent', -- 24601 observations
|
||||
'Aerosol-cool', -- 24560 observations
|
||||
'Trach mask ', -- 16435 observations
|
||||
'High flow neb', -- 10785 observations
|
||||
'Non-rebreather', -- 5182 observations
|
||||
'Venti mask ', -- 1947 observations
|
||||
'Medium conc mask ', -- 1888 observations
|
||||
'T-piece', -- 1135 observations
|
||||
'High flow nasal cannula', -- 925 observations
|
||||
'Ultrasonic neb', -- 9 observations
|
||||
'Vapomist' -- 3 observations
|
||||
) then 1
|
||||
when itemid = 467 and value in
|
||||
(
|
||||
'Cannula', -- 278252 observations
|
||||
'Nasal Cannula', -- 248299 observations
|
||||
-- 'None', -- 95498 observations
|
||||
'Face Tent', -- 35766 observations
|
||||
'Aerosol-Cool', -- 33919 observations
|
||||
'Trach Mask', -- 32655 observations
|
||||
'Hi Flow Neb', -- 14070 observations
|
||||
'Non-Rebreather', -- 10856 observations
|
||||
'Venti Mask', -- 4279 observations
|
||||
'Medium Conc Mask', -- 2114 observations
|
||||
'Vapotherm', -- 1655 observations
|
||||
'T-Piece', -- 779 observations
|
||||
'Hood', -- 670 observations
|
||||
'Hut', -- 150 observations
|
||||
'TranstrachealCat', -- 78 observations
|
||||
'Heated Neb', -- 37 observations
|
||||
'Ultrasonic Neb' -- 2 observations
|
||||
) then 1
|
||||
else 0
|
||||
end
|
||||
) as OxygenTherapy
|
||||
, max(
|
||||
case when itemid is null or value is null then 0
|
||||
-- extubated indicates ventilation event has ended
|
||||
when itemid = 640 and value = 'Extubated' then 1
|
||||
when itemid = 640 and value = 'Self Extubation' then 1
|
||||
else 0
|
||||
end
|
||||
)
|
||||
as Extubated
|
||||
, max(
|
||||
case when itemid is null or value is null then 0
|
||||
when itemid = 640 and value = 'Self Extubation' then 1
|
||||
else 0
|
||||
end
|
||||
)
|
||||
as SelfExtubated
|
||||
from chartevents ce
|
||||
where ce.value is not null
|
||||
-- exclude rows marked as error
|
||||
and (ce.error != 1 or ce.error IS NULL)
|
||||
and itemid in
|
||||
(
|
||||
-- the below are settings used to indicate ventilation
|
||||
720, 223849 -- vent mode
|
||||
, 223848 -- vent type
|
||||
, 445, 448, 449, 450, 1340, 1486, 1600, 224687 -- minute volume
|
||||
, 639, 654, 681, 682, 683, 684,224685,224684,224686 -- tidal volume
|
||||
, 218,436,535,444,224697,224695,224696,224746,224747 -- High/Low/Peak/Mean ("RespPressure")
|
||||
, 221,1,1211,1655,2000,226873,224738,224419,224750,227187 -- Insp pressure
|
||||
, 543 -- PlateauPressure
|
||||
, 5865,5866,224707,224709,224705,224706 -- APRV pressure
|
||||
, 60,437,505,506,686,220339,224700 -- PEEP
|
||||
, 3459 -- high pressure relief
|
||||
, 501,502,503,224702 -- PCV
|
||||
, 223,667,668,669,670,671,672 -- TCPCV
|
||||
, 224701 -- PSVlevel
|
||||
|
||||
-- the below are settings used to indicate extubation
|
||||
, 640 -- extubated
|
||||
|
||||
-- the below indicate oxygen/NIV, i.e. the end of a mechanical vent event
|
||||
, 468 -- O2 Delivery Device#2
|
||||
, 469 -- O2 Delivery Mode
|
||||
, 470 -- O2 Flow (lpm)
|
||||
, 471 -- O2 Flow (lpm) #2
|
||||
, 227287 -- O2 Flow (additional cannula)
|
||||
, 226732 -- O2 Delivery Device(s)
|
||||
, 223834 -- O2 Flow
|
||||
|
||||
-- used in both oxygen + vent calculation
|
||||
, 467 -- O2 Delivery Device
|
||||
)
|
||||
group by icustay_id, charttime
|
||||
UNION DISTINCT
|
||||
-- add in the extubation flags from procedureevents_mv
|
||||
-- note that we only need the start time for the extubation
|
||||
-- (extubation is always charted as ending 1 minute after it started)
|
||||
select
|
||||
icustay_id, starttime as charttime
|
||||
, 0 as MechVent
|
||||
, 0 as OxygenTherapy
|
||||
, 1 as Extubated
|
||||
, case when itemid = 225468 then 1 else 0 end as SelfExtubated
|
||||
from procedureevents_mv
|
||||
where itemid in
|
||||
(
|
||||
227194 -- "Extubation"
|
||||
, 225468 -- "Unplanned Extubation (patient-initiated)"
|
||||
, 225477 -- "Unplanned Extubation (non-patient initiated)"
|
||||
);
|
||||
112
sql/durations/ventilation_durations.sql
Normal file
112
sql/durations/ventilation_durations.sql
Normal file
@@ -0,0 +1,112 @@
|
||||
-- THIS SCRIPT IS AUTOMATICALLY GENERATED. DO NOT EDIT IT DIRECTLY.
|
||||
DROP TABLE IF EXISTS ventilation_durations; CREATE TABLE ventilation_durations AS
|
||||
-- This query extracts the duration of mechanical ventilation
|
||||
-- The main goal of the query is to aggregate sequential ventilator settings
|
||||
-- into single mechanical ventilation "events". The start and end time of these
|
||||
-- events can then be used for various purposes: calculating the total duration
|
||||
-- of mechanical ventilation, cross-checking values (e.g. PaO2:FiO2 on vent), etc
|
||||
|
||||
-- The query's logic is roughly:
|
||||
-- 1) The presence of a mechanical ventilation setting starts a new ventilation event
|
||||
-- 2) Any instance of a setting in the next 8 hours continues the event
|
||||
-- 3) Certain elements end the current ventilation event
|
||||
-- a) documented extubation ends the current ventilation
|
||||
-- b) initiation of non-invasive vent and/or oxygen ends the current vent
|
||||
|
||||
-- See the ventilation_classification.sql query for step 1 of the above.
|
||||
-- This query has the logic for converting events into durations.
|
||||
with vd0 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
-- this carries over the previous charttime which had a mechanical ventilation event
|
||||
, case
|
||||
when MechVent=1 then
|
||||
LAG(CHARTTIME, 1) OVER (partition by icustay_id, MechVent order by charttime)
|
||||
else null
|
||||
end as charttime_lag
|
||||
, charttime
|
||||
, MechVent
|
||||
, OxygenTherapy
|
||||
, Extubated
|
||||
, SelfExtubated
|
||||
from ventilation_classification
|
||||
)
|
||||
, vd1 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, charttime_lag
|
||||
, charttime
|
||||
, MechVent
|
||||
, OxygenTherapy
|
||||
, Extubated
|
||||
, SelfExtubated
|
||||
|
||||
-- if this is a mechanical ventilation event, we calculate the time since the last event
|
||||
, case
|
||||
-- if the current observation indicates mechanical ventilation is present
|
||||
-- calculate the time since the last vent event
|
||||
when MechVent=1 then
|
||||
DATETIME_DIFF(CHARTTIME, charttime_lag, 'MINUTE')/60
|
||||
else null
|
||||
end as ventduration
|
||||
|
||||
, LAG(Extubated,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, case when MechVent=1 or Extubated=1 then 1 else 0 end
|
||||
order by charttime
|
||||
) as ExtubatedLag
|
||||
|
||||
-- now we determine if the current mech vent event is a "new", i.e. they've just been intubated
|
||||
, case
|
||||
-- if there is an extubation flag, we mark any subsequent ventilation as a new ventilation event
|
||||
--when Extubated = 1 then 0 -- extubation is *not* a new ventilation event, the *subsequent* row is
|
||||
when
|
||||
LAG(Extubated,1)
|
||||
OVER
|
||||
(
|
||||
partition by icustay_id, case when MechVent=1 or Extubated=1 then 1 else 0 end
|
||||
order by charttime
|
||||
)
|
||||
= 1 then 1
|
||||
-- if patient has initiated oxygen therapy, and is not currently vented, start a newvent
|
||||
when MechVent = 0 and OxygenTherapy = 1 then 1
|
||||
-- if there is less than 8 hours between vent settings, we do not treat this as a new ventilation event
|
||||
when CHARTTIME > DATETIME_ADD(charttime_lag, INTERVAL '8' HOUR)
|
||||
then 1
|
||||
else 0
|
||||
end as newvent
|
||||
-- use the staging table with only vent settings from chart events
|
||||
FROM vd0 ventsettings
|
||||
)
|
||||
, vd2 as
|
||||
(
|
||||
select vd1.*
|
||||
-- create a cumulative sum of the instances of new ventilation
|
||||
-- this results in a monotonic integer assigned to each instance of ventilation
|
||||
, case when MechVent=1 or Extubated = 1 then
|
||||
SUM( newvent )
|
||||
OVER ( partition by icustay_id order by charttime )
|
||||
else null end
|
||||
as ventnum
|
||||
--- now we convert CHARTTIME of ventilator settings into durations
|
||||
from vd1
|
||||
)
|
||||
-- create the durations for each mechanical ventilation instance
|
||||
select icustay_id
|
||||
-- regenerate ventnum so it's sequential
|
||||
, ROW_NUMBER() over (partition by icustay_id order by ventnum) as ventnum
|
||||
, min(charttime) as starttime
|
||||
, max(charttime) as endtime
|
||||
, DATETIME_DIFF(max(charttime), min(charttime), 'MINUTE')/60 AS duration_hours
|
||||
from vd2
|
||||
group by icustay_id, vd2.ventnum
|
||||
having min(charttime) != max(charttime)
|
||||
-- patient had to be mechanically ventilated at least once
|
||||
-- i.e. max(mechvent) should be 1
|
||||
-- this excludes a frequent situation of NIV/oxygen before intub
|
||||
-- in these cases, ventnum=0 and max(mechvent)=0, so they are ignored
|
||||
and max(mechvent) = 1
|
||||
order by icustay_id, ventnum
|
||||
207
sql/durations/weight_durations.sql
Normal file
207
sql/durations/weight_durations.sql
Normal file
@@ -0,0 +1,207 @@
|
||||
-- THIS SCRIPT IS AUTOMATICALLY GENERATED. DO NOT EDIT IT DIRECTLY.
|
||||
DROP TABLE IF EXISTS weight_durations; CREATE TABLE weight_durations AS
|
||||
-- This query extracts weights for adult ICU patients with start/stop times
|
||||
-- if an admission weight is given, then this is assigned from intime to outtime
|
||||
|
||||
-- This query extracts weights for adult ICU patients with start/stop times
|
||||
-- if an admission weight is given, then this is assigned from intime to outtime
|
||||
WITH wt_neonate AS
|
||||
(
|
||||
SELECT c.icustay_id, c.charttime
|
||||
, MAX(CASE WHEN c.itemid = 3580 THEN c.valuenum END) as wt_kg
|
||||
, MAX(CASE WHEN c.itemid = 3581 THEN c.valuenum END) as wt_lb
|
||||
, MAX(CASE WHEN c.itemid = 3582 THEN c.valuenum END) as wt_oz
|
||||
FROM chartevents c
|
||||
WHERE c.itemid in (3580, 3581, 3582)
|
||||
AND c.icustay_id IS NOT NULL
|
||||
AND COALESCE(c.error, 0) = 0
|
||||
-- wt_oz/wt_lb/wt_kg are only 0 erroneously, so drop these rows
|
||||
AND c.valuenum > 0
|
||||
-- a separate query was run to manually verify only 1 value exists per
|
||||
-- icustay_id/charttime/itemid grouping
|
||||
-- therefore, we can use max() across itemid to collapse these values to 1 row per group
|
||||
GROUP BY c.icustay_id, c.charttime
|
||||
)
|
||||
, birth_wt AS
|
||||
(
|
||||
SELECT c.icustay_id, c.charttime
|
||||
, MAX(
|
||||
CASE
|
||||
WHEN c.itemid = 4183 THEN
|
||||
-- clean free-text birth weight data
|
||||
CASE
|
||||
-- ignore value if there are any non-numeric characters
|
||||
WHEN REGEXP_CONTAINS(c.value, '[^0-9\\.]') THEN NULL
|
||||
-- convert grams to kd
|
||||
WHEN CAST(c.value AS NUMERIC) > 100 THEN CAST(c.value AS NUMERIC)/1000
|
||||
-- keep kg as is, filtering bad values (largest baby ever born was conveniently 9.98kg)
|
||||
WHEN CAST(c.value AS NUMERIC) < 10 THEN CAST(c.value AS NUMERIC)
|
||||
-- ignore other values (those between 10-100) - junk data
|
||||
ELSE NULL END
|
||||
-- itemid 3723 happily has all numeric data - also doesn't store any grams data
|
||||
WHEN c.itemid = 3723 AND c.valuenum < 10 THEN c.valuenum
|
||||
ELSE NULL END) as wt_kg
|
||||
FROM chartevents c
|
||||
WHERE c.itemid in (3723, 4183)
|
||||
AND c.icustay_id IS NOT NULL
|
||||
AND COALESCE(c.error, 0) = 0
|
||||
-- a separate query was run to manually verify only 1 value exists per
|
||||
-- icustay_id/charttime/itemid grouping
|
||||
-- therefore, we can use max() across itemid to collapse these values to 1 row per group
|
||||
GROUP BY c.icustay_id, c.charttime
|
||||
)
|
||||
, wt_stg as
|
||||
(
|
||||
SELECT
|
||||
c.icustay_id
|
||||
, c.charttime
|
||||
, case when c.itemid in (762,226512) then 'admit'
|
||||
else 'daily' end as weight_type
|
||||
-- TODO: eliminate obvious outliers if there is a reasonable weight
|
||||
, c.valuenum as weight
|
||||
FROM chartevents c
|
||||
WHERE c.valuenum IS NOT NULL
|
||||
AND c.itemid in
|
||||
(
|
||||
762,226512 -- Admit Wt
|
||||
, 763,224639 -- Daily Weight
|
||||
)
|
||||
AND c.icustay_id IS NOT NULL
|
||||
AND c.valuenum > 0
|
||||
-- exclude rows marked as error
|
||||
AND COALESCE(c.error, 0) = 0
|
||||
UNION ALL
|
||||
SELECT
|
||||
n.icustay_id
|
||||
, n.charttime
|
||||
, 'daily' AS weight_type
|
||||
, CASE
|
||||
WHEN wt_kg IS NOT NULL THEN wt_kg
|
||||
WHEN wt_lb IS NOT NULL THEN wt_lb*0.45359237 + wt_oz*0.0283495231
|
||||
ELSE NULL END AS weight
|
||||
FROM wt_neonate n
|
||||
UNION ALL
|
||||
SELECT
|
||||
b.icustay_id
|
||||
, b.charttime
|
||||
-- birth weight of neonates is treated as admission weight
|
||||
, 'admit' AS weight_type
|
||||
, wt_kg as weight
|
||||
FROM birth_wt b
|
||||
)
|
||||
-- get more weights from echo - completes data for ~2500 patients
|
||||
-- we only use echo data if there is *no* charted data
|
||||
-- we impute the median echo weight for their entire ICU stay
|
||||
, echo as
|
||||
(
|
||||
select
|
||||
ie.icustay_id
|
||||
, ec.charttime
|
||||
, 'echo' AS weight_type
|
||||
, 0.453592*ec.weight as weight
|
||||
from icustays ie
|
||||
inner join echo_data ec
|
||||
on ie.hadm_id = ec.hadm_id
|
||||
where ec.weight is not null
|
||||
and ie.icustay_id not in (select distinct icustay_id from wt_stg)
|
||||
)
|
||||
, wt_stg0 AS
|
||||
(
|
||||
SELECT icustay_id, charttime, weight_type, weight
|
||||
FROM wt_stg
|
||||
UNION ALL
|
||||
SELECT icustay_id, charttime, weight_type, weight
|
||||
FROM echo
|
||||
)
|
||||
-- assign ascending row number
|
||||
, wt_stg1 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, charttime
|
||||
, weight_type
|
||||
, weight
|
||||
, ROW_NUMBER() OVER (partition by icustay_id, weight_type order by charttime) as rn
|
||||
from wt_stg0
|
||||
WHERE weight IS NOT NULL
|
||||
)
|
||||
-- change charttime to intime for the first admission weight recorded
|
||||
, wt_stg2 AS
|
||||
(
|
||||
SELECT
|
||||
wt_stg1.icustay_id
|
||||
, ie.intime, ie.outtime
|
||||
, case when wt_stg1.weight_type = 'admit' and wt_stg1.rn = 1
|
||||
then DATETIME_SUB(ie.intime, INTERVAL '2' HOUR)
|
||||
else wt_stg1.charttime end as starttime
|
||||
, wt_stg1.weight
|
||||
from wt_stg1
|
||||
INNER JOIN icustays ie
|
||||
on ie.icustay_id = wt_stg1.icustay_id
|
||||
)
|
||||
, wt_stg3 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, intime, outtime
|
||||
, starttime
|
||||
, coalesce(
|
||||
LEAD(starttime) OVER (PARTITION BY icustay_id ORDER BY starttime),
|
||||
DATETIME_ADD(GREATEST(outtime, starttime), INTERVAL '2' HOUR)
|
||||
) as endtime
|
||||
, weight
|
||||
from wt_stg2
|
||||
)
|
||||
-- this table is the start/stop times from admit/daily weight in charted data
|
||||
, wt1 as
|
||||
(
|
||||
select
|
||||
icustay_id
|
||||
, starttime
|
||||
, coalesce(endtime,
|
||||
LEAD(starttime) OVER (partition by icustay_id order by starttime),
|
||||
-- impute ICU discharge as the end of the final weight measurement
|
||||
-- plus a 2 hour "fuzziness" window
|
||||
DATETIME_ADD(outtime, INTERVAL '2' HOUR)
|
||||
) as endtime
|
||||
, weight
|
||||
from wt_stg3
|
||||
)
|
||||
-- if the intime for the patient is < the first charted daily weight
|
||||
-- then we will have a "gap" at the start of their stay
|
||||
-- to prevent this, we look for these gaps and backfill the first weight
|
||||
-- this adds (153255-149657)=3598 rows, meaning this fix helps for up to 3598 icustay_id
|
||||
, wt_fix as
|
||||
(
|
||||
select ie.icustay_id
|
||||
-- we add a 2 hour "fuzziness" window
|
||||
, DATETIME_SUB(ie.intime, INTERVAL '2' HOUR) as starttime
|
||||
, wt.starttime as endtime
|
||||
, wt.weight
|
||||
from icustays ie
|
||||
inner join
|
||||
-- the below subquery returns one row for each unique icustay_id
|
||||
-- the row contains: the first starttime and the corresponding weight
|
||||
(
|
||||
SELECT wt1.icustay_id, wt1.starttime, wt1.weight
|
||||
, ROW_NUMBER() OVER (PARTITION BY wt1.icustay_id ORDER BY wt1.starttime) as rn
|
||||
FROM wt1
|
||||
) wt
|
||||
ON ie.icustay_id = wt.icustay_id
|
||||
AND wt.rn = 1
|
||||
and ie.intime < wt.starttime
|
||||
)
|
||||
-- add the backfill rows to the main weight table
|
||||
select
|
||||
wt1.icustay_id
|
||||
, wt1.starttime
|
||||
, wt1.endtime
|
||||
, wt1.weight
|
||||
from wt1
|
||||
UNION ALL
|
||||
SELECT
|
||||
wt_fix.icustay_id
|
||||
, wt_fix.starttime
|
||||
, wt_fix.endtime
|
||||
, wt_fix.weight
|
||||
from wt_fix
|
||||
Reference in New Issue
Block a user