Penilaian Tanda Vital, Riwayat Penyakit dan Hasil Lab Test Pada Pasien ICU di Rumah Sakit

By Delvia

Photo by Kaleigh Fasanella

1 Introduction

Kematian di rumah sakit khususnya pada kasus gagal jantung di unit perawatan intensif (ICU) menjadi fokus utama pada bagian ini. Berdasarkan referensi dataset, tujuan dataset ini disusun adalah untuk menganalisis status vital pasien sebagai sebagai orang yang selamat (alive) dan tidak selamat (death). Dataset diambil menggunakan SQL dan PostgreSQL meliputi data demografis pasien, tanda vital, riwayat penyakit serta hasil laboratorium. Pada penulisan kali ini, kita akan menganalisis dan menilai lebih jauh mengenai kondisi pasien gagal jantung yang dirawat di ICU rumah sakit.

Berikut adalah dataset yang digunakan pada pembahasan Rpubs kali ini. Data ini dapat diakses dari Kaggle.

2 Import Library

library(rmdformats)
library(tidyr)
library(ggplot2)
library(dplyr)
library(GGally)
library(psych)
library(zoo)
library(inspectdf)

3 Read Data

mortality <- read.csv("data input/data01.csv") # import dataset
rmarkdown::paged_table(mortality)

Mengubah Tipe Data

Terdapat beberapa kolom yang sebaiknya dihapus dan diganti tipe datanya sebagai berikut

mortality_clean <- mortality %>% 
  mutate(gendera=as.factor(ifelse(gendera == "1", "female", "male")),
         hypertensive=as.factor(ifelse(hypertensive == "1", "yes", "no")),
         atrialfibrillation=as.factor(ifelse(atrialfibrillation == "1", "yes", "no")),
         CHD.with.no.MI=as.factor(ifelse(CHD.with.no.MI == "1", "yes", "no")),
         diabetes=as.factor(ifelse(diabetes == "1", "yes", "no")),
         deficiencyanemias=as.factor(ifelse(deficiencyanemias == "1", "yes", "no")),
         depression=as.factor(ifelse(depression == "1", "yes", "no")),
         Hyperlipemia=as.factor(ifelse(Hyperlipemia == "1", "yes", "no")),
         Renal.failure=as.factor(ifelse(Renal.failure == "1", "yes", "no")),
         COPD=as.factor(ifelse(COPD == "1", "yes", "no")),
         outcome = as.factor(ifelse(outcome == "1", "death", "alive"))) %>% 
  select(-c(group, ID))
  

glimpse(mortality_clean)
#> Rows: 1,177
#> Columns: 49
#> $ outcome                  <fct> alive, alive, alive, alive, alive, alive, ali…
#> $ age                      <int> 72, 75, 83, 43, 75, 76, 72, 83, 61, 67, 70, 8…
#> $ gendera                  <fct> female, male, male, male, male, female, femal…
#> $ BMI                      <dbl> 37.58818, NA, 26.57263, 83.26463, 31.82484, 2…
#> $ hypertensive             <fct> no, no, no, no, yes, yes, yes, yes, yes, yes,…
#> $ atrialfibrillation       <fct> no, no, no, no, no, yes, no, yes, yes, no, no…
#> $ CHD.with.no.MI           <fct> no, no, no, no, no, no, no, no, no, no, no, n…
#> $ diabetes                 <fct> yes, no, no, no, no, no, no, yes, yes, yes, y…
#> $ deficiencyanemias        <fct> yes, yes, yes, no, yes, yes, no, yes, no, no,…
#> $ depression               <fct> no, no, no, no, no, no, no, no, no, no, no, n…
#> $ Hyperlipemia             <fct> yes, no, no, no, no, yes, yes, no, no, no, ye…
#> $ Renal.failure            <fct> yes, no, yes, no, yes, yes, yes, no, yes, no,…
#> $ COPD                     <fct> no, yes, no, no, yes, yes, yes, no, no, no, n…
#> $ heart.rate               <dbl> 68.83784, 101.37037, 72.31818, 94.50000, 67.9…
#> $ Systolic.blood.pressure  <dbl> 155.86667, 140.00000, 135.33333, 126.40000, 1…
#> $ Diastolic.blood.pressure <dbl> 68.33333, 65.00000, 61.37500, 73.20000, 58.12…
#> $ Respiratory.rate         <dbl> 16.62162, 20.85185, 23.64000, 21.85714, 21.36…
#> $ temperature              <dbl> 36.71429, 36.68254, 36.45370, 36.28704, 36.76…
#> $ SP.O2                    <dbl> 98.39474, 96.92308, 95.29167, 93.84615, 99.28…
#> $ Urine.output             <dbl> 2155, 1425, 2425, 8760, 4455, 1840, 2450, 303…
#> $ hematocrit               <dbl> 26.27273, 30.78000, 27.70000, 36.63750, 29.93…
#> $ RBC                      <dbl> 2.960000, 3.138000, 2.620000, 4.277500, 3.286…
#> $ MCH                      <dbl> 28.25000, 31.06000, 34.32000, 26.06250, 30.66…
#> $ MCHC                     <dbl> 31.52000, 31.66000, 31.30000, 30.41250, 33.66…
#> $ MCV                      <dbl> 89.90000, 98.20000, 109.80000, 85.62500, 91.0…
#> $ RDW                      <dbl> 16.22000, 14.26000, 23.82000, 17.03750, 16.26…
#> $ Leucocyte                <dbl> 7.6500000, 12.7400000, 5.4800000, 8.2250000, …
#> $ Platelets                <dbl> 305.10000, 246.40000, 204.20000, 216.37500, 2…
#> $ Neutrophils              <dbl> 74.65000, NA, 68.10000, 81.80000, NA, 85.4000…
#> $ Basophils                <dbl> 0.40, NA, 0.55, 0.15, NA, 0.30, 0.20, NA, 0.5…
#> $ Lymphocyte               <dbl> 13.300000, NA, 24.500000, 14.500000, NA, 9.30…
#> $ PT                       <dbl> 10.60000, NA, 11.27500, 27.06667, NA, 18.7833…
#> $ INR                      <dbl> 1.000000, NA, 0.950000, 2.666667, NA, 1.70000…
#> $ NT.proBNP                <dbl> 1956.0, 2384.0, 4081.0, 668.0, 30802.0, 34183…
#> $ Creatine.kinase          <dbl> 148.00000, 60.60000, 16.00000, 85.00000, 111.…
#> $ Creatinine               <dbl> 1.9583333, 1.1222222, 1.8714286, 0.5857143, 1…
#> $ Urea.nitrogen            <dbl> 50.00000, 20.33333, 33.85714, 15.28571, 43.00…
#> $ glucose                  <dbl> 114.63636, 147.50000, 149.00000, 128.25000, 1…
#> $ Blood.potassium          <dbl> 4.816667, 4.450000, 5.825000, 4.386667, 4.783…
#> $ Blood.sodium             <dbl> 138.7500, 138.8889, 140.7143, 138.5000, 136.6…
#> $ Blood.calcium            <dbl> 7.463636, 8.162500, 8.266667, 9.476923, 8.733…
#> $ Chloride                 <dbl> 109.16667, 98.44444, 105.85714, 92.07143, 104…
#> $ Anion.gap                <dbl> 13.166667, 11.444444, 10.000000, 12.357143, 1…
#> $ Magnesium.ion            <dbl> 2.618182, 1.887500, 2.157143, 1.942857, 1.650…
#> $ PH                       <dbl> 7.230000, 7.225000, 7.268000, 7.370000, 7.250…
#> $ Bicarbonate              <dbl> 21.16667, 33.44444, 30.57143, 38.57143, 22.00…
#> $ Lactic.acid              <dbl> 0.5000000, 0.5000000, 0.5000000, 0.6000000, 0…
#> $ PCO2                     <dbl> 40.00000, 78.00000, 71.50000, 75.00000, 50.00…
#> $ EF                       <int> 55, 55, 35, 55, 55, 35, 55, 75, 50, 55, 75, 5…

Description
Dataset terdiri dari 49 kolom di antaranya:
* data demografis pasien : umur, jenis kelamin, index massa tubuh
* tanda vital : laju detak jantung (heart.rate), tekanan darah (Systolic.blood.pressure & Diastolic.blood.pressure), laju pernapasan (Respiratory.rate), suhu tubuh (temperature), Normal oxygen saturation levels (SP.O2), urin 24 jam pertama (Urine.output)
* riwayat penyakit : hypertensive, atrialfibrillation, penyakit jantung iskemik tanpa infark miokard (CHD.with.no.MI), diabetes, depression anemia (deficiencyanemias), hiperlipidemia (Hyperlipemia), penyakit ginjal kronis (Renal.failure), dan penyakit paru obstruktif kronik (COPD)
* hasil laboratorium mencakup:
- sel darah: hematocrit, eritrosit (RBC), rata-rata jumlah hemoglobin dalam satu eritrosit (MCH), rata-rata konsentrasi hemoglobin dalam satu eritrosit (MCHC), volume rata-rata eritrosit (MCV), variasi ukuran eritrosit (RDW), jumlah trombosit (Platelets), sel darah putih (Leucocyte), Neutrophils, Basophils, Lymphocyte
- Faktor pembekuan darah: waktu protrombin (PT), laju pembekuan darah (INR)
- Parameter gagal jantung: NT-proBNP, Left ventricular ejection fraction (EF)
- Parameter diabetes: gula darah (glucose)
- Parameter asidosis metabolik: nitrogen urea darah (BUN), Urea.nitrogen, celah anion (Anion.gap), Bicarbonate, Lactic.acid, konsentrasi ion hidrogen (pH), Creatinine, Creatine.kinase
- Jumlah mineral dalam darah: kalium (Blood.potassium), natrium (Blood.sodium), kalsium (Blood.calcium), klorida (Chloride), magnesium (Magnesium.ion), tekanan parsial CO2 dalam darah arteri (PCO2)

4 Data Wrangling

# cek data duplikat
anyDuplicated(mortality_clean)
#> [1] 0

Tidak terdapat duplikat pada data. Selanjutnya, akan dilakukan pengecekan pada missing value

# cek missing value
is.na(mortality_clean) %>% colSums()
#>                  outcome                      age                  gendera 
#>                        1                        0                        0 
#>                      BMI             hypertensive       atrialfibrillation 
#>                      215                        0                        0 
#>           CHD.with.no.MI                 diabetes        deficiencyanemias 
#>                        0                        0                        0 
#>               depression             Hyperlipemia            Renal.failure 
#>                        0                        0                        0 
#>                     COPD               heart.rate  Systolic.blood.pressure 
#>                        0                       13                       16 
#> Diastolic.blood.pressure         Respiratory.rate              temperature 
#>                       16                       13                       19 
#>                    SP.O2             Urine.output               hematocrit 
#>                       13                       36                        0 
#>                      RBC                      MCH                     MCHC 
#>                        0                        0                        0 
#>                      MCV                      RDW                Leucocyte 
#>                        0                        0                        0 
#>                Platelets              Neutrophils                Basophils 
#>                        0                      144                      259 
#>               Lymphocyte                       PT                      INR 
#>                      145                       20                       20 
#>                NT.proBNP          Creatine.kinase               Creatinine 
#>                        0                      165                        0 
#>            Urea.nitrogen                  glucose          Blood.potassium 
#>                        0                       18                        0 
#>             Blood.sodium            Blood.calcium                 Chloride 
#>                        0                        1                        0 
#>                Anion.gap            Magnesium.ion                       PH 
#>                        0                        0                      292 
#>              Bicarbonate              Lactic.acid                     PCO2 
#>                        0                      229                      294 
#>                       EF 
#>                        0

Ternyata, dari hasil pengecekan terdapat beberapa kolom yang memiliki nilai missing value. Pertama-tama mari kita cek grafik persebaran data numerik. Namun, karena jumlah kolomnya sangat banyak, maka pengecekan kolom nya akan dibagi menjadi dua bagian.

mortality_clean %>% 
  select_if(is.numeric) %>% 
  select_if(anyNA) %>% 
  select(1:9) %>% 
  pairs.panels() # persebaran data 9 kolom pertama yang mengandung missing value

mortality_clean %>% 
  select_if(is.numeric) %>% 
  select_if(anyNA) %>% 
  select(10:19) %>% 
  pairs.panels() # persebaran data 10 kolom terakhir yang mengandung missing value

Bila dilihat persebaran datanya, maka keduanya cenderung mengalami skewed positif. Berdasarkan literatur [https://medium.com/analytics-vidhya/appropriate-ways-to-treat-missing-values-f82f00edd9be], bila terdapat data yang skewed maka disarankan untuk mengisi missing value dengan nilai median atau modus. Dalam hal ini kita akan isi missing value dengan menggunakan nilai median.

mortality_clean <- mortality_clean %>% 
  mutate_if(is.numeric, na.aggregate, FUN=median) %>% # mengisi semua nilai missing value dengan median
  filter(complete.cases(.)) # drop 1 row yang kolom outcomenya masih kosong
anyNA(mortality_clean) # re-check ulang nilai missing value
#> [1] FALSE

Setelah dicek ulang ternyata data kita sudah tidak memiliki nilai missing value. # 5 Exploratory Data Analysis (EDA) ### Data Clean Berikut adalah data clean yang telah diproses sebelumnya.

rmarkdown::paged_table(head(mortality_clean))

Business Knowledge

Berikut adalah nilai normal lab test yang dapat dijadikan referensi

Notes:
- BMI: <18.5 (Underweight), 25.0 to 29.9 (Overweight I), 30.0 (Overweight II), 30 to <35 (obesity I), 35 to <40 (obesity II), >=40 (obesity III)

Overview

Sebelum melakukan eksploratori lebih jauh, kita akan melihat nilai korelasi antar variabel untuk melihat apakah terdapat hubungan antar variabel yang dapat mempermudah analisis lebih lanjut.

ggcorr(mortality_clean %>% 
      select_if(is.numeric) %>% 
        select(-c(RDW,MCV,MCHC,MCH,RBC,hematocrit, Blood.potassium,Blood.sodium,Blood.calcium, Chloride)), label = T, label_round = 3, label_size=2)

Insight:
- PT berkorelasi positif kuat dengan INR sebesar 0.987
- PCO2 berkorelasi positif kuat dengan Bicarbonate sebesar 0.679
- Creatinine berkorelasi positif kuat dengan Urea.nitrogen sebesar 0.608
- glucose berkorelasi positif kuat dengan Creatinine sebesar 0.576
- glucose berkorelasi positif kuat dengan Urea.nitrogen sebesar 0.523
- PCO2 berkorelasi cukup kuat negatif dengan PH sebesar -0.415

Mari kita lihat dua plot dengan nilai korelasi tertinggi

plot(mortality_clean$PT, mortality_clean$INR)
abline(lm(mortality_clean$INR ~ mortality_clean$PT), # garis linear `lm` 
       col = 'red')

💡 Insight:
Semakin tinggi nilai PT (Prothrombin Time), maka nilai INR (International Ratio Unit) juga semakin tinggi. INR merupakan hasil perhitungan berdasarkan nilai PT pasien, dimana keduanya berbanding lurus. Baik PT maupun INR digunakan untuk mendiagnosa perdarahan (bleeding) ataupun pembekuan darah (blood clot), serta untuk memantau penggunaan obat antikoagulan yang biasanya digunakan pada pasien dengan indikasi atrial fibrilation ataupun gagal jantung yang memiliki resiko tinggi terhadap blood clot.

plot(mortality_clean$Bicarbonate, mortality_clean$PCO2)
abline(lm(mortality_clean$PCO2 ~ mortality_clean$Bicarbonate), # garis linear `lm` 
       col = 'red')

💡 Insight:
Semakin tinggi nilai PCO2, maka semakin tinggi juga nilai Bicarbonate dengan nilai korelasi -0.415, yang artinya semakin tinggi nilai PCO2, maka semakin rendah nilai PH (keasaman darah meningkat). Hal ini sesuai dengan literatur bahwa peningkatan PCO2 akan menyebabkan peningkatan ventilasi udara akibatnya terjadi perubahan kadar asam-basa dalam darah yang tentunya hal ini menjadi sinyal bagi ginjal untuk melepaskan sejumlah bikarbonat untuk menjaga homeostatis, akibatnya pH darah menjadi asam (<7.35) dan kadar bikarbonat tinggi(>29mEq/L).

# Categoric Variable Proportion
x2 <- inspect_cat(mortality_clean) 
show_plot(x2)

💡 Insight:
Top 3 riwayat penyakit yang banyak dialami oleh pasien adalah riwayat hipertensi, atrialfibrillation dan diabetes.

Mari kita lihat persebaran data kategorik menggunakan fungsi summary()

mortality_clean %>% 
  select_if(is.factor) %>% 
  summary()
#>   outcome       gendera    hypertensive atrialfibrillation CHD.with.no.MI
#>  alive:1017   female:558   no :332      no :645            no :1075      
#>  death: 159   male  :618   yes:844      yes:531            yes: 101      
#>  diabetes  deficiencyanemias depression Hyperlipemia Renal.failure  COPD     
#>  no :681   no :777           no :1036   no :729      no :747       no :1087  
#>  yes:495   yes:399           yes: 140   yes:447      yes:429       yes:  89

💡 Insight:
- Terdapat 159 pasien yang meninggal dan 1017 pasien yang bertahan hidup di ruang ICU Rumah sakit
- Mayoritas pasien memiliki rentang umur 65 - 85 tahun yang didominasi oleh pasien pria yakni 618 dan wanita sebanyak 558
- Berdasarkan riwayat penyakit, kasus riwayat pasien di ruang ICU diantaranya hipertensi sebanyak 844 kasus, gagal jantung tanpa infark-miokard sebanyak 101, diabetes sebanyak 495, anemia sebanyak 399, depresi sebanyak 140, hiperlipidemia sebanyak 447, gagal ginjal sebanyak 429, dan Penyakit paru obstruktif kronis sebanyak 89 kasus.

Distribusi Data Umur

hist(mortality_clean$age)

plot(mortality_clean$outcome, mortality_clean$age, horizontal=T)

summary(mortality_clean$age)
#>    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
#>   19.00   65.00   77.00   74.05   85.00   99.00
a <- nrow(mortality_clean[mortality_clean$age>=18 & mortality_clean$age<65 & mortality_clean$outcome=="death",]) # jumlah pasien adults yang meninggal sebanyak 26
b <- nrow(mortality_clean[mortality_clean$age>=65 & mortality_clean$outcome=="death",]) # jumlah pasien geriatri yang meninggal sebanyak 133
b/a # perbandingan jumlah pasien geriatri dan adults yang meninggal
#> [1] 5.115385

💡 Insight:
- Terdapat dua kelompok pasien pada data yaitu kelompok adults (18-65 tahun) dan geriatri (>65 tahun), dimana jumlah pasien geriatri yang meninggal 5 kali lipat dibandingkan kelompok adults.

summary(mortality_clean[mortality_clean$outcome=="alive", c("age")])
#>    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
#>   19.00   65.00   77.00   73.71   85.00   98.00

💡 Insight:
- Pasien yang hidup umumnya berada di range umur 65-85, dimana datanya berpusat pada umur 77 tahun

summary(mortality_clean[mortality_clean$outcome=="death", c("age")])
#>    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
#>   28.00   69.50   80.00   76.24   86.00   99.00

💡 Insight:
- Range umur pasien yang meninggal berada pada di sekitar 70-90, dimana datanya berpusat pada umur 80 tahun

Distribusi jenis kelamin

nrow(mortality_clean[mortality_clean$gendera=="male" & mortality_clean$outcome=="death",])
#> [1] 79
nrow(mortality_clean[mortality_clean$gendera=="female" & mortality_clean$outcome=="death",])
#> [1] 80

💡 Insight:
- Tidak terdapat perbedaan signifikan kasus kematian yang terjadi pada pria maupun wanita. Sehingga, mungkin dapat dikatakan bahwa probabilitas kematian keduanya sama.

Distribusi Riwayat hipertensi

hist(mortality_clean$Systolic.blood.pressure)

💡 Insight:
- Nilai tekanan darah sistolik terbanyak terdapat pada range 100-130 mmHg. Berdasarkan tabel referensi nilai normal lab test, maka range tersebut menunjukkan bahwa nilai nya di bawah normal. Pada kasus gagal jantung, tekanan darah sistolik mungkin rendah, normal atau tinggi tergantung pada tingkat keparahannya. Namun, umumnya kemampuan jantung dalam berkontraksi dan memompa darah berkurang sehingga menyebabkan tekanan darah sistolik menurun. Menurut penelitian, tekanan darah sistolik <120 mmHg berkaitan dengan tingginya resiko kematian pada jangka waktu 30 hari, 1 tahun dan jangka panjang.

hist(mortality_clean$Diastolic.blood.pressure)

💡 Insight:
- Nilai tekanan darah diastolik terbanyak terdapat pada range 50-65, yang juga menunjukkan nilai di bawah normal. Tekanan darah diastolik sendiri merupakan tekanan di arteri ketika jantung beristirahat. Karena tekanan sistolik berkurang, akibatnya tekanan diastolik juga berkurang.

c <- nrow(mortality_clean[mortality_clean$hypertensive=="yes" & mortality_clean$outcome=="death",])# jumlah pasien yang meninggal dengan riwayat hipertensi ada sebanyak 101
d <- nrow(mortality_clean[mortality_clean$hypertensive=="no" & mortality_clean$outcome=="death",])# jumlah pasien yang meninggal dengan tanpa riwayat hipertensi ada sebanyak 58
c/d
#> [1] 1.741379

💡 Insight:
- Jumlah pasien meninggal dengan riwayat hipertensi ada sebanyak 101 dan yang tidak memiliki riwayat hipertensi ada sebanyak 58. Sehingga, mungkin dapat dikatakan bahwa probabilitas pasien yang meninggal dengan riwayat hipertensi hampir 2 kali lipat dibandingkan dengan yang tidak. Hal yang perlu menjadi perhatian adalah sangat memungkinkan jika pasien dengan riwayat hipertensi dan gagal jantung mengalami penurunan tekanan darah baik sistolik maupun diastolik karena kemampuan jantung dalam memompa darah secara efektif terganggu. Selain itu, penggunaan obat untuk mengatasi gagal jantung maupun hipertensi seperti anti-diuretik dapat menyebabkan penurunan tekanan darah secara drastis, sehingga perlu pemantauan khusus oleh tenaga medis.

Distribusi Riwayat Atrial fibrillation

e <- nrow(mortality_clean[mortality_clean$atrialfibrillation=="yes" & mortality_clean$outcome=="death",])# jumlah pasien yang meninggal dengan riwayat atrialfibrillation ada sebanyak 92
f <- nrow(mortality_clean[mortality_clean$atrialfibrillation=="no" & mortality_clean$outcome=="death",])# jumlah pasien yang meninggal dengan tanpa riwayat atrialfibrillation ada sebanyak 67
e/f
#> [1] 1.373134

💡 Insight:
- Jumlah pasien meninggal dengan riwayat atrialfibrillation ada sebanyak 92 dan yang tidak memiliki riwayat atrialfibrillation ada sebanyak 67. Sehingga, mungkin dapat dikatakan bahwa probabilitas pasien yang meninggal dengan riwayat atrialfibrillation 1.37 kali lipat dibandingkan dengan yang tidak. Dalam beberapa kasus, atrial fibrillation dapat menyebabkan gagal jantung. Atrial fibrillation merupakan kondisi dimana ritme jantung tidak teratur sehingga seiring berjalannya waktu, hal ini akan melemahkan otot jantung dan mengakibatkan gagal jantung. Selain itu, akibat ritme jantung yg tidak teratur juga, menyebabkan darah menggenang di jantung dan meningkatkan resiko penggumpalan darah (blood clot). Namun, sebaliknya gagal jantung dapat menyebabkan atrial fibrillation. Pasien yang mengalami gagal jantung dan atrial fibrillation sekaligus akan sulit ditreatment karena rentan mengalami komplikasi seperti stroke.

Distribusi Riwayat Diabetes

nrow(mortality_clean[mortality_clean$diabetes=="yes" & mortality_clean$outcome=="death",])# jumlah pasien yang meninggal dengan riwayat diabetes ada sebanyak 57
#> [1] 57
nrow(mortality_clean[mortality_clean$diabetes=="no" & mortality_clean$outcome=="death",])# jumlah pasien yang meninggal dengan tanpa riwayat diabetes ada sebanyak 102
#> [1] 102

💡 Insight:
- Jumlah pasien meninggal dengan riwayat diabetes hanya 57 sementara yang meninggal tanpa riwayat diabetes lebih banyak yaitu 102.

Abnormal Anion Gap

hist(mortality_clean$Anion.gap, breaks=50)

💡 Insight:
- Nilai anion gap terbanyak terdapat pada range 12-15 mEq/L. Meskipun ada beberapa kasus dimana nilai anion gap berada di atas nilai normal. Tingginya nilai anion gap dapat menjadi indikasi kadar asam dalam darah tidak seimbang, contohnya pada kasus asidosis metabolik dengan gejala seperti penurunan tekanan darah, denyut jantung menjadi cepat, dan lain-lain. Namun, perlu diketahui bahwa nilai anion gap ini tidak bisa dijadikan sebagai acuan dalam mengindikasikan suatu penyakit.

plot(mortality_clean$outcome, mortality_clean$Anion.gap, horizontal=T)

💡 Insight:
- Berdasarkan hasil plot, diketahui bahwa beberapa pasien yang meninggal adalah pasien dengan nilai anion gap di atas nilai normal.

nrow(mortality_clean[((mortality_clean$Anion.gap>11 & mortality_clean$age<65) | (mortality_clean$Anion.gap>16 & mortality_clean$age>=65)) & mortality_clean$outcome=="death",])# jumlah pasien yang meninggal dengan anion gap abnormal ada sebanyak 75
#> [1] 75
nrow(mortality_clean[((mortality_clean$Anion.gap>11 & mortality_clean$age<65) | (mortality_clean$Anion.gap>16 & mortality_clean$age>=65)) & mortality_clean$outcome=="alive",])# jumlah pasien yang hidup dengan anion gap abnormal ada sebanyak 327
#> [1] 327

💡 Insight:
- Jumlah pasien yang meninggal dengan anion gap abnormal ada sebanyak 75. Sementara, pasien yang hidup dengan anion gap abnormal ada sebanyak 327.

Indikasi Heart failure

hist(mortality_clean$NT.proBNP, breaks=50)

💡 Insight:
- Nilai NT.proBNP paling banyak terdapat pada range <8000 pg/mL. NT.proBNP merupakan salah satu indikator parameter dalam menentukan gagal jantung pada tahap awal. Selain itu, parameter ini juga dapat digunakan sebagai indikasi penyakit lain seperti iskemia, takikardia, penyakit paru obstruktif kronis (COPD), embolisme paru, gagal ginjal, sepsis, sirosis hati, sindrom koroner akut, miokarditis dan disfungsi katup jantung.

hist(mortality_clean$EF)

💡 Insight:
- Nilai Ejection fraction (EF) terbanyak terdapat pada range 45-55. EF digunakan untuk mengukur jumlah darah yang dipompa keluar dari ventrikel untuk diedarkan ke seluruh tubuh. Selain NT.proBNP, EF juga digunakan untuk penegakan diagnosa gagal jantung.

plot(mortality_clean$outcome, mortality_clean$NT.proBNP, horizontal=T)

💡 Insight:
- Pasien yang hidup umumnya memiliki nilai NT-proBNP yang normal yaitu <300. Sebaliknya, pasien yang meninggal memiliki kecenderungan nilai NT-proBNP yang abnormal yaitu >300

plot(mortality_clean$outcome, mortality_clean$EF, horizontal=T)

💡 Insight:
- Pasien yang hidup umumnya memiliki nilai EF>50. Sebaliknya, pasien yang meninggal memiliki kecenderungan nilai EF yang abnormal yaitu <50.

Selanjutnya, kita akan membuat dataframe baru dengan fokus terhadap kasus gagal jantung

kardiopulmonologi <- mortality_clean %>% 
  select(-c(hematocrit, MCH, MCHC, MCV, RDW, Creatine.kinase, Blood.potassium, Blood.sodium, Blood.calcium, Chloride, Magnesium.ion))
# add new column possible_heart_failure
kardiopulmonologi$possible_heart_failure <- ifelse(kardiopulmonologi$NT.proBNP > 300 & kardiopulmonologi$EF < 50, "heart failure", "no heart failure")
kardiopulmonologi$possible_heart_failure <- as.factor(kardiopulmonologi$possible_heart_failure)

#add new column possible_infection
kardiopulmonologi$possible_infection <- ifelse(kardiopulmonologi$Leucocyte > 11 & (kardiopulmonologi$Lymphocyte>4.5 | kardiopulmonologi$Basophils>0.22), "infection", "no infection")
kardiopulmonologi$possible_infection <- as.factor(kardiopulmonologi$possible_infection)
plot(kardiopulmonologi$possible_heart_failure)

💡 Insight:
- Jumlah pasien gagal jantung ada sebanyak 362 dan yang tidak gagal jantung sebanyak 814

data <- kardiopulmonologi[,c(39,40)]
counts <- table(data)

# Convert the counts to a data frame
counts_df <- data.frame(counts)

# Create a stacked bar plot
ggplot(counts_df, aes(x=Freq, y=possible_heart_failure, fill=possible_infection)) + 
  geom_bar(stat="identity") +
  labs(x="Count", y="possible_heart_failure", fill="possible_infection") +
  ggtitle("Infection by Heart Failure")

💡 Insight:
- Dari 362 pasien gagal jantung, 139 diantaranya memiliki indikasi infeksi. Sementara itu, dari 814 yang tidak gagal jantung yang mengalami infeksi sebanyak 267. Total infeksi yang terjadi ada sebanyak 406 kasus. Infeksi dapat berkembang menjadi gagal jantung meskipun hal ini komplikasi yang jarang terjadi. Pada beberapa kasus, infeksi tertentu seperti virus ataupun bakteri dapat mengakibatkan peradangan pada otot jantung (miokarditis), juga dapat menyebabkan kerusakan otot jantung yang dapat menurunkan kemampuannya dalam memompa darah dan dapat berkembang menjadi gagal jantung.

Selain itu, infeksi juga dapat menyebabkan sepsis, yaitu kondisi dimana sistem imun tubuh bereaksi secara berlebihan dalam merespon imun yang menyebabkan pelepasan sejumlah besar senyawa kimia ke dalam darah. Hal ini akan berkembang menjadi kerusakan pada beberapa jaringan/organ termasuk jantung.

data1 <- kardiopulmonologi[,c(5,39)]
counts1 <- table(data1)

# Convert the counts to a data frame
counts_df1 <- data.frame(counts1)

# Create a stacked bar plot
ggplot(counts_df1, aes(x=Freq, y=possible_heart_failure, fill=hypertensive)) + 
  geom_bar(stat="identity") +
  labs(x="Count", y="possible_heart_failure", fill="hypertensive") +
  ggtitle("Heart Failure by Hypertensive")

💡 Insight:
- Dari 362 pasien gagal jantung, 264 diantaranya memiliki riwayat hipertensi. Sementara itu, dari 814 yang tidak gagal jantung yang memiliki riwayat hipertensi sebanyak 580. Total kasus hipertensi yang terjadi ada sebanyak 844 kasus.

data2 <- kardiopulmonologi[,c(8,39)]
counts2 <- table(data2)

# Convert the counts to a data frame
counts_df2 <- data.frame(counts2)

# Create a stacked bar plot
ggplot(counts_df2, aes(x=Freq, y=possible_heart_failure, fill=diabetes)) + 
  geom_bar(stat="identity") +
  labs(x="Count", y="possible_heart_failure", fill="diabetes") +
  ggtitle("Heart Failure by diabetes")

💡 Insight:
- Dari 362 pasien gagal jantung, 154 diantaranya memiliki riwayat diabetes. Sementara itu, dari 814 yang tidak gagal jantung yang memiliki riwayat diabetes sebanyak 341. Total kasus diabetes yang terjadi ada sebanyak 495 kasus.

data3 <- kardiopulmonologi[,c(6,39)]
counts3 <- table(data3)

# Convert the counts to a data frame
counts_df3 <- data.frame(counts3)

# Create a stacked bar plot
ggplot(counts_df3, aes(x=Freq, y=possible_heart_failure, fill=atrialfibrillation)) + 
  geom_bar(stat="identity") +
  labs(x="Count", y="possible_heart_failure", fill="atrialfibrillation") +
  ggtitle("Heart Failure by atrialfibrillation")

💡 Insight:
- Dari 362 pasien gagal jantung, 173 diantaranya memiliki riwayat atrial fibrillation. Sementara itu, dari 814 yang tidak gagal jantung yang memiliki riwayat atrial fibrillation sebanyak 358. Total kasus atrial fibrillation yang terjadi ada sebanyak 531 kasus.

data4 <- kardiopulmonologi[,c(11,39)]
counts4 <- table(data4)

# Convert the counts to a data frame
counts_df4 <- data.frame(counts4)

# Create a stacked bar plot
ggplot(counts_df4, aes(x=Freq, y=possible_heart_failure, fill=Hyperlipemia)) + 
  geom_bar(stat="identity") +
  labs(x="Count", y="possible_heart_failure", fill="Hyperlipemia") +
  ggtitle("Heart Failure by Hyperlipemia")

💡 Insight:
- Dari 362 pasien gagal jantung, 161 diantaranya memiliki riwayat hiperlipidemia. Sementara itu, dari 814 yang tidak gagal jantung yang memiliki riwayat hiperlipidemia sebanyak 286. Total kasus hiperlipidemia yang terjadi ada sebanyak 447 kasus.

6 Kesimpulan

data5 <- kardiopulmonologi[,c(1,39)]
counts5 <- table(data5)

# Convert the counts to a data frame
counts_df5 <- data.frame(counts5)
counts_df5
#>   outcome possible_heart_failure Freq
#> 1   alive          heart failure  303
#> 2   death          heart failure   59
#> 3   alive       no heart failure  714
#> 4   death       no heart failure  100
table(kardiopulmonologi$outcome)
#> 
#> alive death 
#>  1017   159

Dari analisis di atas, kita dapat menarik informasi:
- Sangat sulit dalam menentukan faktor kematian pasien gagal jantung, karena ada banyak sekali parameter yang harus dipertimbangkan
- Penyakit gagal jantung merupakan penyakit yang diakibatkan oleh beberapa faktor diantaranya hipertensi, infeksi, atrial fibrilation, diabetes, dan lain-lain. Namun, sebaliknya faktor-faktor tersebut justru juga dapat berkembang menjadi gagal jantung
- Pada dataset ini diperoleh informasi bahwa jumlah kematian di ICU rumah sakit khususnya pada kasus gagal jantung ada sekitar 159 dibanding yang hidup sekitar 1017. Dari 159 pasien yang meninggal, 59 diantaranya memiliki indikasi gagal jantung.