-- ------------------------------------------------------------------ -- All-time arterial blood-gas pivot (PaO2 / FiO2 ratio at every gas). -- -- This script is a fusion of the upstream MIMIC-III concepts_postgres -- files -- firstday/blood_gas_first_day.sql -- firstday/blood_gas_first_day_arterial.sql -- with their day-1 time predicate removed, so we get one row per -- (icustay_id, charttime) for the entire ICU stay. -- -- Output table: blood_gas_arterial -- Output cols : subject_id, hadm_id, icustay_id, charttime, -- specimen, specimen_pred, specimen_prob, -- so2, spo2, po2, pco2, fio2_chartevents, fio2, -- aado2, aado2_calc, pao2fio2, ph, baseexcess, -- bicarbonate, totalco2, hematocrit, hemoglobin, -- carboxyhemoglobin, methemoglobin, chloride, calcium, -- temperature, potassium, sodium, lactate, glucose, -- intubated, tidalvolume, ventilationrate, ventilator, -- peep, o2flow, requiredo2 -- -- Restricted to *arterial* samples (specimen = 'ART' or -- specimen_prob > 0.75). -- ------------------------------------------------------------------ DROP TABLE IF EXISTS blood_gas_arterial; CREATE TABLE blood_gas_arterial AS WITH bg_pvt AS ( SELECT ie.subject_id, ie.hadm_id, ie.icustay_id , CASE WHEN itemid = 50800 THEN 'SPECIMEN' WHEN itemid = 50801 THEN 'AADO2' WHEN itemid = 50802 THEN 'BASEEXCESS' WHEN itemid = 50803 THEN 'BICARBONATE' WHEN itemid = 50804 THEN 'TOTALCO2' WHEN itemid = 50805 THEN 'CARBOXYHEMOGLOBIN' WHEN itemid = 50806 THEN 'CHLORIDE' WHEN itemid = 50808 THEN 'CALCIUM' WHEN itemid = 50809 THEN 'GLUCOSE' WHEN itemid = 50810 THEN 'HEMATOCRIT' WHEN itemid = 50811 THEN 'HEMOGLOBIN' WHEN itemid = 50812 THEN 'INTUBATED' WHEN itemid = 50813 THEN 'LACTATE' WHEN itemid = 50814 THEN 'METHEMOGLOBIN' WHEN itemid = 50815 THEN 'O2FLOW' WHEN itemid = 50816 THEN 'FIO2' WHEN itemid = 50817 THEN 'SO2' WHEN itemid = 50818 THEN 'PCO2' WHEN itemid = 50819 THEN 'PEEP' WHEN itemid = 50820 THEN 'PH' WHEN itemid = 50821 THEN 'PO2' WHEN itemid = 50822 THEN 'POTASSIUM' WHEN itemid = 50823 THEN 'REQUIREDO2' WHEN itemid = 50824 THEN 'SODIUM' WHEN itemid = 50825 THEN 'TEMPERATURE' WHEN itemid = 50826 THEN 'TIDALVOLUME' WHEN itemid = 50827 THEN 'VENTILATIONRATE' WHEN itemid = 50828 THEN 'VENTILATOR' ELSE NULL END AS label , le.charttime , le.value , CASE WHEN valuenum <= 0 AND itemid != 50802 THEN NULL WHEN itemid = 50810 AND valuenum > 100 THEN NULL WHEN itemid = 50816 AND valuenum < 20 THEN NULL WHEN itemid = 50816 AND valuenum > 100 THEN NULL WHEN itemid = 50817 AND valuenum > 100 THEN NULL WHEN itemid = 50815 AND valuenum > 70 THEN NULL WHEN itemid = 50821 AND valuenum > 800 THEN NULL ELSE valuenum END AS valuenum FROM icustays ie INNER JOIN labevents le ON le.subject_id = ie.subject_id AND le.hadm_id = ie.hadm_id AND le.charttime BETWEEN ie.intime AND ie.outtime AND le.itemid IN ( 50800,50801,50802,50803,50804,50805,50806,50807,50808,50809 , 50810,50811,50812,50813,50814,50815,50816,50817,50818,50819 , 50820,50821,50822,50823,50824,50825,50826,50827,50828 , 51545 ) ) , bg AS ( SELECT subject_id, hadm_id, icustay_id, charttime , MAX(CASE WHEN label = 'SPECIMEN' THEN value END) AS specimen , MAX(CASE WHEN label = 'AADO2' THEN valuenum END) AS aado2 , MAX(CASE WHEN label = 'BASEEXCESS' THEN valuenum END) AS baseexcess , MAX(CASE WHEN label = 'BICARBONATE' THEN valuenum END) AS bicarbonate , MAX(CASE WHEN label = 'TOTALCO2' THEN valuenum END) AS totalco2 , MAX(CASE WHEN label = 'CARBOXYHEMOGLOBIN' THEN valuenum END) AS carboxyhemoglobin , MAX(CASE WHEN label = 'CHLORIDE' THEN valuenum END) AS chloride , MAX(CASE WHEN label = 'CALCIUM' THEN valuenum END) AS calcium , MAX(CASE WHEN label = 'GLUCOSE' THEN valuenum END) AS glucose , MAX(CASE WHEN label = 'HEMATOCRIT' THEN valuenum END) AS hematocrit , MAX(CASE WHEN label = 'HEMOGLOBIN' THEN valuenum END) AS hemoglobin , MAX(CASE WHEN label = 'INTUBATED' THEN valuenum END) AS intubated , MAX(CASE WHEN label = 'LACTATE' THEN valuenum END) AS lactate , MAX(CASE WHEN label = 'METHEMOGLOBIN' THEN valuenum END) AS methemoglobin , MAX(CASE WHEN label = 'O2FLOW' THEN valuenum END) AS o2flow , MAX(CASE WHEN label = 'FIO2' THEN valuenum END) AS fio2 , MAX(CASE WHEN label = 'SO2' THEN valuenum END) AS so2 , MAX(CASE WHEN label = 'PCO2' THEN valuenum END) AS pco2 , MAX(CASE WHEN label = 'PEEP' THEN valuenum END) AS peep , MAX(CASE WHEN label = 'PH' THEN valuenum END) AS ph , MAX(CASE WHEN label = 'PO2' THEN valuenum END) AS po2 , MAX(CASE WHEN label = 'POTASSIUM' THEN valuenum END) AS potassium , MAX(CASE WHEN label = 'REQUIREDO2' THEN valuenum END) AS requiredo2 , MAX(CASE WHEN label = 'SODIUM' THEN valuenum END) AS sodium , MAX(CASE WHEN label = 'TEMPERATURE' THEN valuenum END) AS temperature , MAX(CASE WHEN label = 'TIDALVOLUME' THEN valuenum END) AS tidalvolume , MAX(CASE WHEN label = 'VENTILATIONRATE' THEN valuenum END) AS ventilationrate , MAX(CASE WHEN label = 'VENTILATOR' THEN valuenum END) AS ventilator FROM bg_pvt GROUP BY subject_id, hadm_id, icustay_id, charttime ) , stg_spo2 AS ( SELECT subject_id, hadm_id, icustay_id, charttime , MAX(CASE WHEN valuenum <= 0 OR valuenum > 100 THEN NULL ELSE valuenum END) AS spo2 FROM chartevents WHERE itemid IN (646, 220277) GROUP BY subject_id, hadm_id, icustay_id, charttime ) , stg_fio2 AS ( SELECT subject_id, hadm_id, icustay_id, charttime , MAX( CASE WHEN itemid = 223835 THEN CASE WHEN valuenum > 0 AND valuenum <= 1 THEN valuenum * 100 WHEN valuenum > 1 AND valuenum < 21 THEN NULL WHEN valuenum >= 21 AND valuenum <= 100 THEN valuenum ELSE NULL END WHEN itemid IN (3420, 3422) THEN valuenum WHEN itemid = 190 AND valuenum > 0.20 AND valuenum < 1 THEN valuenum * 100 ELSE NULL END ) AS fio2_chartevents FROM chartevents WHERE itemid IN (3420, 190, 223835, 3422) AND COALESCE(error, 0) = 0 GROUP BY subject_id, hadm_id, icustay_id, charttime ) , stg2 AS ( SELECT bg.* , ROW_NUMBER() OVER ( PARTITION BY bg.icustay_id, bg.charttime ORDER BY s1.charttime DESC ) AS lastrowspo2 , s1.spo2 FROM bg LEFT JOIN stg_spo2 s1 ON bg.icustay_id = s1.icustay_id AND s1.charttime >= DATETIME_SUB(bg.charttime, INTERVAL '2' HOUR) AND s1.charttime <= bg.charttime WHERE bg.po2 IS NOT NULL ) , stg3 AS ( SELECT stg2.* , ROW_NUMBER() OVER ( PARTITION BY stg2.icustay_id, stg2.charttime ORDER BY s2.charttime DESC ) AS lastrowfio2 , s2.fio2_chartevents , 1 / (1 + EXP(-(-0.02544 + 0.04598 * po2 + COALESCE(-0.15356 * spo2 , -0.15356 * 97.49420 + 0.13429) + COALESCE( 0.00621 * s2.fio2_chartevents, 0.00621 * 51.49550 + -0.24958) + COALESCE( 0.10559 * hemoglobin , 0.10559 * 10.32307 + 0.05954) + COALESCE( 0.13251 * so2 , 0.13251 * 93.66539 + -0.23172) + COALESCE(-0.01511 * pco2 , -0.01511 * 42.08866 + -0.01630) + COALESCE( 0.01480 * fio2 , 0.01480 * 63.97836 + -0.31142) + COALESCE(-0.00200 * aado2 , -0.00200 * 442.21186 + -0.01328) + COALESCE(-0.03220 * bicarbonate , -0.03220 * 22.96894 + -0.06535) + COALESCE( 0.05384 * totalco2 , 0.05384 * 24.72632 + -0.01405) + COALESCE( 0.08202 * lactate , 0.08202 * 3.06436 + 0.06038) + COALESCE( 0.10956 * ph , 0.10956 * 7.36233 + -0.00617) + COALESCE( 0.00848 * o2flow , 0.00848 * 7.59362 + -0.35803) ))) AS specimen_prob FROM stg2 LEFT JOIN stg_fio2 s2 ON stg2.icustay_id = s2.icustay_id AND s2.charttime BETWEEN DATETIME_SUB(stg2.charttime, INTERVAL '4' HOUR) AND stg2.charttime WHERE stg2.lastrowspo2 = 1 ) SELECT subject_id, hadm_id, icustay_id, charttime , specimen , CASE WHEN specimen IS NOT NULL THEN specimen WHEN specimen_prob > 0.75 THEN 'ART' ELSE NULL END AS specimen_pred , specimen_prob , so2, spo2, po2, pco2 , fio2_chartevents, fio2 , aado2 , CASE WHEN po2 IS NOT NULL AND pco2 IS NOT NULL AND COALESCE(fio2, fio2_chartevents) IS NOT NULL THEN (COALESCE(fio2, fio2_chartevents) / 100) * (760 - 47) - (pco2 / 0.8) - po2 ELSE NULL END AS aado2_calc , CASE WHEN po2 IS NOT NULL AND COALESCE(fio2, fio2_chartevents) IS NOT NULL THEN 100 * po2 / COALESCE(fio2, fio2_chartevents) ELSE NULL END AS pao2fio2 , ph, baseexcess, bicarbonate, totalco2 , hematocrit, hemoglobin, carboxyhemoglobin, methemoglobin , chloride, calcium, temperature, potassium, sodium, lactate, glucose , intubated, tidalvolume, ventilationrate, ventilator , peep, o2flow, requiredo2 FROM stg3 WHERE lastrowfio2 = 1 AND (specimen = 'ART' OR specimen_prob > 0.75); CREATE INDEX IF NOT EXISTS blood_gas_arterial_idx ON blood_gas_arterial (icustay_id, charttime);