## Soal 1 (a) - Pengecekan Data

# Load library
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.3.3
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.3.3
# Load data
data <- read.csv("C:/Users/ASUS/OneDrive/Documents/PROJECT_PSDA_NAI/heart_dataproject_psda.csv", sep = ";")

# Cek Missing Values
colSums(is.na(data))
##      age      sex       cp trestbps     chol      fbs  restecg  thalach 
##        0        0        0        0        0        0        0        0 
##    exang  oldpeak    slope       ca     thal   target 
##        0        0        0        0        0        0
# Cek Data Duplikat
sum(duplicated(data))
## [1] 1
# Hapus duplikat
data <- data[!duplicated(data), ]

# Ringkasan Statistik
summary(data)
##       age             sex               cp            trestbps    
##  Min.   :29.00   Min.   :0.0000   Min.   :0.0000   Min.   : 94.0  
##  1st Qu.:48.00   1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.:120.0  
##  Median :55.50   Median :1.0000   Median :1.0000   Median :130.0  
##  Mean   :54.42   Mean   :0.6821   Mean   :0.9636   Mean   :131.6  
##  3rd Qu.:61.00   3rd Qu.:1.0000   3rd Qu.:2.0000   3rd Qu.:140.0  
##  Max.   :77.00   Max.   :1.0000   Max.   :3.0000   Max.   :200.0  
##       chol            fbs           restecg          thalach     
##  Min.   :126.0   Min.   :0.000   Min.   :0.0000   Min.   : 71.0  
##  1st Qu.:211.0   1st Qu.:0.000   1st Qu.:0.0000   1st Qu.:133.2  
##  Median :240.5   Median :0.000   Median :1.0000   Median :152.5  
##  Mean   :246.5   Mean   :0.149   Mean   :0.5265   Mean   :149.6  
##  3rd Qu.:274.8   3rd Qu.:0.000   3rd Qu.:1.0000   3rd Qu.:166.0  
##  Max.   :564.0   Max.   :1.000   Max.   :2.0000   Max.   :202.0  
##      exang           oldpeak           slope             ca        
##  Min.   :0.0000   Min.   :0.0000   Min.   :0.000   Min.   :0.0000  
##  1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.:1.000   1st Qu.:0.0000  
##  Median :0.0000   Median :0.0800   Median :1.000   Median :0.0000  
##  Mean   :0.3278   Mean   :0.7957   Mean   :1.397   Mean   :0.7185  
##  3rd Qu.:1.0000   3rd Qu.:1.0600   3rd Qu.:2.000   3rd Qu.:1.0000  
##  Max.   :1.0000   Max.   :6.0200   Max.   :2.000   Max.   :4.0000  
##       thal           target     
##  Min.   :0.000   Min.   :0.000  
##  1st Qu.:2.000   1st Qu.:0.000  
##  Median :2.000   Median :1.000  
##  Mean   :2.315   Mean   :0.543  
##  3rd Qu.:3.000   3rd Qu.:1.000  
##  Max.   :3.000   Max.   :1.000
# Visualisasi outlier
boxplot(data$chol, main = "Boxplot Kolesterol", col = "lightblue")

boxplot(data$trestbps, main = "Boxplot Tekanan Darah", col = "lightgreen")

boxplot(data$oldpeak, main = "Boxplot Oldpeak", col = "lightpink")

Setelah dilakukan pemeriksaan:

Interpretasi Statistik Deskriptif:

Temuan ini menggambarkan sebaran kondisi medis dari pasien, dan penting sebagai dasar analisis selanjutnya.

## Soal 1 (b) - Visualisasi Gender, Usia, dan Gula Darah

# Konversi sex ke faktor dengan label
data$sex <- factor(data$sex, labels = c("Perempuan", "Laki-laki"))

# Barplot jenis kelamin vs heart disease
ggplot(data, aes(x = sex, fill = factor(target))) +
  geom_bar(position = "dodge") +
  labs(title = "Jumlah Heart Disease Berdasarkan Jenis Kelamin",
       x = "Jenis Kelamin", y = "Jumlah",
       fill = "Heart Disease (1=Ya, 0=Tidak)") +
  theme_minimal()

# Histogram usia penderita heart disease
ggplot(data[data$target == 1, ], aes(x = age)) +
  geom_histogram(binwidth = 5, fill = "tomato", color = "black") +
  labs(title = "Distribusi Usia Penderita Heart Disease",
       x = "Usia", y = "Frekuensi") +
  theme_minimal()

# Histogram usia dengan fbs > 120
ggplot(data[data$fbs == 1, ], aes(x = age)) +
  geom_histogram(binwidth = 5, fill = "skyblue", color = "black") +
  labs(title = "Distribusi Usia Pasien dengan Gula Darah > 120 mg/dl",
       x = "Usia", y = "Frekuensi") +
  theme_minimal()

Interpretasi, Visualisasi ini bertujuan untuk melihat:

## Soal 1 (c) - Apakah Gula Darah > 120 Berpengaruh?

# Konversi fbs ke faktor
data$fbs <- factor(data$fbs, labels = c("≤ 120 mg/dl", "> 120 mg/dl"))

# Barplot fbs vs target
ggplot(data, aes(x = fbs, fill = factor(target))) +
  geom_bar(position = "dodge") +
  labs(title = "Heart Disease Berdasarkan Kadar Gula Darah",
       x = "Kadar Gula Darah (FBS)", y = "Jumlah",
       fill = "Heart Disease (1=Ya, 0=Tidak)") +
  theme_minimal()

# Tabel ringkasan
table(data$fbs, data$target)
##              
##                 0   1
##   ≤ 120 mg/dl 116 141
##   > 120 mg/dl  22  23

Setelah membandingkan jumlah penderita heart disease berdasarkan kadar gula darah (fbs):

Interpretasi:

Berdasarkan barplot dan tabel kontingensi, jumlah penderita heart disease dengan kadar gula darah > 120 tidak lebih banyak dibandingkan yang memiliki kadar gula normal. Ini menunjukkan bahwa fbs > 120 bukan indikator utama terhadap penyakit jantung dalam dataset ini.

## Soal 1 (d) - Siapa yang Lebih Banyak Mengalami Heart Disease?

# Barplot gender vs heart disease
ggplot(data, aes(x = sex, fill = factor(target))) +
  geom_bar(position = "dodge") +
  labs(title = "Heart Disease Berdasarkan Jenis Kelamin",
       x = "Jenis Kelamin", y = "Jumlah",
       fill = "Heart Disease (1=Ya, 0=Tidak)") +
  theme_minimal()

# Konversi variabel cp
data$cp <- factor(data$cp, labels = c(
  "Typical Angina", 
  "Atypical Angina", 
  "Non-anginal Pain", 
  "Asymptomatic"
))

# Barplot cp vs heart disease
ggplot(data, aes(x = cp, fill = factor(target))) +
  geom_bar(position = "dodge") +
  labs(title = "Heart Disease Berdasarkan Jenis Nyeri Dada (Chest Pain)",
       x = "Tipe Chest Pain", y = "Jumlah",
       fill = "Heart Disease (1=Ya, 0=Tidak)") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 30, hjust = 1))

# Konversi restecg
data$restecg <- factor(data$restecg, labels = c(
  "Normal", 
  "ST-T Wave Abnormalitas", 
  "Left Ventricular Hypertrophy"
))

# Barplot restecg vs heart disease
ggplot(data, aes(x = restecg, fill = factor(target))) +
  geom_bar(position = "dodge") +
  labs(title = "Heart Disease Berdasarkan Hasil EKG (restecg)",
       x = "Hasil EKG", y = "Jumlah",
       fill = "Heart Disease (1=Ya, 0=Tidak)") +
  theme_minimal()

Dari visualisasi barplot:

Interpretasi:

Jenis nyeri dada Asymptomatic menjadi salah satu karakteristik penting pada penderita heart disease dan perlu perhatian lebih karena gejalanya tidak kentara.

## Soal 1 (e) - Barplot Heart Disease terhadap cp, ca, thal

# Ubah cp jadi faktor dengan label
data$cp <- factor(data$cp, labels = c(
  "Typical Angina", 
  "Atypical Angina", 
  "Non-anginal Pain", 
  "Asymptomatic"
))

# Ubah ca jadi faktor
data$ca <- as.factor(data$ca)

# Cek level unik untuk thal agar tahu berapa label yg dibutuhkan
table(data$thal)  # Gunakan ini sekali sebelum konversi
## 
##   0   1   2   3 
##   2  18 165 117
# Jika ternyata ada 4 level (misal 0,1,2,3), beri 4 label
data$thal <- factor(data$thal, labels = c(
  "Unknown", "Normal", "Fixed Defect", "Reversible Defect"
))

# Barplot proporsi heart disease terhadap cp
ggplot(data, aes(x = cp, fill = factor(target))) +
  geom_bar(position = "fill") +
  labs(title = "Proporsi Heart Disease berdasarkan Chest Pain Type",
       x = "Chest Pain Type", y = "Proporsi", fill = "Heart Disease (1=Ya, 0=Tidak)") +
  theme_minimal()

# Barplot proporsi heart disease terhadap ca
ggplot(data, aes(x = ca, fill = factor(target))) +
  geom_bar(position = "fill") +
  labs(title = "Proporsi Heart Disease berdasarkan CA",
       x = "Jumlah Pembuluh Darah Berwarna (ca)", y = "Proporsi", fill = "Heart Disease") +
  theme_minimal()

# Barplot proporsi heart disease terhadap thal
ggplot(data, aes(x = thal, fill = factor(target))) +
  geom_bar(position = "fill") +
  labs(title = "Proporsi Heart Disease berdasarkan Thalassemia",
       x = "Thalassemia", y = "Proporsi", fill = "Heart Disease") +
  theme_minimal()

Interpretasi:

## Soal 1 (f) - Eksplorasi hubungan age dan thalach berdasarkan target

# Scatter plot age vs thalach, dibedakan berdasarkan status heart disease
ggplot(data, aes(x = age, y = thalach, color = factor(target))) +
  geom_point(alpha = 0.5) +
  geom_smooth(method = "loess", formula = y ~ x) +
  labs(title = "Hubungan antara Usia dan Denyut Jantung Maksimum",
       x = "Usia",
       y = "Thalach (Detak Jantung Maksimum)",
       color = "Heart Disease (0=Tidak, 1=Ya)") +
  theme_minimal()

Plot scatter antara age dan thalach (detak jantung maksimum) memperlihatkan:

Interpretasi:

## Soal 1 (g) - Heatmap Korelasi antar Variabel Numerik

# Load library tambahan
library(corrplot)
## Warning: package 'corrplot' was built under R version 4.3.3
## corrplot 0.95 loaded
# Pilih variabel numerik saja
data_numeric <- data %>%
  select_if(is.numeric)

# Hitung korelasi
cor_matrix <- cor(data_numeric)

# Visualisasi heatmap korelasi
corrplot(cor_matrix, method = "color", type = "upper", 
         tl.col = "black", tl.srt = 45, 
         addCoef.col = "black", number.cex = 0.7,
         col = colorRampPalette(c("red", "white", "blue"))(200),
         title = "Heatmap Korelasi Antar Variabel", 
         mar = c(0,0,1,0))

Heatmap korelasi digunakan untuk melihat hubungan antar variabel numerik. Beberapa hasil penting:

Interpretasi:

Korelasi ini membantu dalam proses pemodelan dan pemilihan fitur yang relevan dalam prediksi penyakit jantun

Soal 1 (h) – Summary hasil analisis

Berdasarkan analisis eksploratif yang telah dilakukan dari soal (a) hingga (g), diperoleh sejumlah temuan penting yang berkaitan dengan faktor-faktor yang memengaruhi keberadaan penyakit jantung pada individu:

Hasil Analisis:

  • Distribusi variabel numerik seperti kolesterol (chol) dan tekanan darah istirahat (trestbps) menunjukkan adanya outlier, yang dapat merepresentasikan risiko klinis tertentu.
  • Hasil visualisasi barplot pada variabel kategorik (cp, ca, dan thal) mengindikasikan bahwa individu dengan tipe nyeri dada Asymptomatic, jumlah pembuluh darah utama yang terblokir lebih dari satu, serta jenis thalassemia Fixed Defect atau Reversible Defect, lebih berisiko menderita penyakit jantung.
  • Hubungan antara usia (age) dan detak jantung maksimum (thalach) bersifat negatif dan cenderung non-linear, terutama pada pasien dengan penyakit jantung.
  • Korelasi antar variabel numerik menunjukkan bahwa variabel oldpeak dan age berkorelasi negatif dengan thalach, sedangkan oldpeak memiliki korelasi positif dengan kemungkinan menderita penyakit jantung.

Indikasi Penyakit Jantung:

Dari hasil eksplorasi, beberapa karakteristik yang menjadi indikasi kuat adanya penyakit jantung antara lain:

  • Nyeri dada tipe Asymptomatic.
  • Nilai ca ≥ 1, yaitu jumlah pembuluh darah utama yang mengalami penyumbatan.
  • Tipe thalassemia berupa Fixed Defect dan Reversible Defect.
  • Nilai thalach yang rendah (detak jantung maksimum rendah), terutama pada kelompok usia lebih tua.
  • Nilai oldpeak yang tinggi dan hasil EKG (restecg) abnormal.

Hal-hal yang dapat membantu mencegah penyakit jantung:

Beberapa hal yang dapat membantu menurunkan risiko penyakit jantung di antaranya:

  • Menerapkan gaya hidup sehat melalui olahraga rutin, konsumsi makanan bergizi, dan manajemen stres.
  • Melakukan kontrol rutin terhadap tekanan darah, kolesterol, dan gula darah.
  • Melakukan deteksi dini terhadap gejala penyakit jantung, terutama bagi individu dengan riwayat keluarga terkait.
  • Menjaga berat badan ideal dan menghentikan kebiasaan merokok.
  • Melakukan pemeriksaan kesehatan secara berkala, khususnya untuk individu berusia di atas 45 tahun.

Kesimpulan:

Analisis data ini menunjukkan bahwa terdapat beberapa variabel yang dapat digunakan sebagai indikator awal untuk mendeteksi potensi penyakit jantung, serta mendukung pentingnya pendekatan preventif dan promotif dalam kesehatan jantung. Penelitian lanjutan dengan metode statistik inferensial atau pemodelan prediktif dapat dilakukan untuk menguatkan temuan ini.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

## Soal 2 - ## Soal 2 - Visualisasi Hubungan Konsumsi Listrik dan Biaya per kWh
# Load library
library(ggplot2)
library(dplyr)

# Buat data
data <- data.frame(
  No = 1:24,
  Konsumsi_GWh = c(10, 20, 30, 50, 70, 90, 
                   40, 80, 120, 200, 300, 400,
                   15, 25, 35, 50, 70,
                   5, 10, 15, 20, 25, 30, 40),
  Biaya_per_kWh = c(1500, 1450, 1400, 1350, 1300, 1250,
                    1300, 1250, 1200, 1150, 1100, 1050,
                    1600, 1550, 1500, 1450, 1400,
                    1700, 1600, 1550, 1500, 1450, 1400, 1350),
  Konsumen = c(rep("Rumah Tangga", 6),
               rep("Industri", 6),
               rep("Kantor Pemerintah", 5),
               rep("UMKM", 7))
)

# Visualisasi
ggplot(data, aes(x = Konsumsi_GWh, y = Biaya_per_kWh, color = Konsumen)) +
  geom_point(size = 2) +
  geom_smooth(method = "lm", se = FALSE, formula = y ~ x) +  # ← perbaikan di sini
  scale_y_continuous(labels = scales::comma) +
  labs(
    title = "Biaya Listrik per kWh Menurun Seiring Kenaikan Konsumsi",
    x = "Total Konsumsi Listrik (GWh)",
    y = "Biaya per kWh (Rupiah)"
  ) +
  theme_minimal()

### Penjelasan Sintaks:

  • library(ggplot2) dan library(dplyr): Mengimpor library yang digunakan untuk visualisasi dan manipulasi data.
  • data.frame(…): Membuat data simulasi yang terdiri dari 24 observasi, dengan variabel Konsumsi_GWh, Biaya_per_kWh, dan Konsumen.
  • ggplot(…): Membuat kerangka visualisasi menggunakan ggplot2.
  • aes(x, y, color = Konsumen): Menentukan sumbu X dan Y serta pewarnaan berdasarkan jenis konsumen.
  • geom_point(size = 2): Menampilkan titik-titik data dengan ukuran tertentu.
  • geom_smooth(…): Menambahkan garis regresi linear (tanpa shading se = FALSE) untuk masing-masing kelompok konsumen.
  • scale_y_continuous(labels = scales::comma): Format label sumbu Y dengan pemisah ribuan (mis. 1,500).
  • labs(…): Memberikan judul grafik dan label sumbu X dan Y.
  • theme_minimal(): Memberikan tampilan minimalis dan bersih pada grafik.

Interpertasi:

  • Grafik menunjukkan bahwa biaya per kWh cenderung menurun seiring peningkatan konsumsi listrik.
  • Pola ini tampak konsisten di semua jenis konsumen: Rumah Tangga, Industri, Kantor Pemerintah, dan UMKM.
  • Kelompok Industri dan UMKM memiliki tingkat konsumsi yang lebih tinggi namun mendapatkan biaya per kWh yang lebih rendah, menandakan adanya tarif insentif atau efisiensi skala.
  • Sebaliknya, konsumen Rumah Tangga cenderung membayar tarif lebih tinggi per kWh, meskipun konsumsi mereka lebih rendah.