1. Load dan Cek Data

data <- read.csv("C:/Users/PC-MS/OneDrive/Documents/PSD/heart.csv")
str(data)
## 'data.frame':    303 obs. of  14 variables:
##  $ age     : int  63 37 41 56 57 57 56 44 52 57 ...
##  $ sex     : int  1 1 0 1 0 1 0 1 1 1 ...
##  $ cp      : int  3 2 1 1 0 0 1 1 2 2 ...
##  $ trestbps: int  145 130 130 120 120 140 140 120 172 150 ...
##  $ chol    : int  233 250 204 236 354 192 294 263 199 168 ...
##  $ fbs     : int  1 0 0 0 0 0 0 0 1 0 ...
##  $ restecg : int  0 1 0 1 1 1 0 1 1 1 ...
##  $ thalach : int  150 187 172 178 163 148 153 173 162 174 ...
##  $ exang   : int  0 0 0 0 1 0 0 0 0 0 ...
##  $ oldpeak : num  2.3 3.5 1.4 0.8 0.6 0.4 1.3 0 0.5 1.6 ...
##  $ slope   : int  0 0 2 2 2 1 1 2 2 2 ...
##  $ ca      : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ thal    : int  1 2 2 2 2 1 2 3 3 2 ...
##  $ target  : int  1 1 1 1 1 1 1 1 1 1 ...
summary(data)
##       age             sex               cp           trestbps    
##  Min.   :29.00   Min.   :0.0000   Min.   :0.000   Min.   : 94.0  
##  1st Qu.:47.50   1st Qu.:0.0000   1st Qu.:0.000   1st Qu.:120.0  
##  Median :55.00   Median :1.0000   Median :1.000   Median :130.0  
##  Mean   :54.37   Mean   :0.6832   Mean   :0.967   Mean   :131.6  
##  3rd Qu.:61.00   3rd Qu.:1.0000   3rd Qu.:2.000   3rd Qu.:140.0  
##  Max.   :77.00   Max.   :1.0000   Max.   :3.000   Max.   :200.0  
##       chol            fbs            restecg          thalach     
##  Min.   :126.0   Min.   :0.0000   Min.   :0.0000   Min.   : 71.0  
##  1st Qu.:211.0   1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.:133.5  
##  Median :240.0   Median :0.0000   Median :1.0000   Median :153.0  
##  Mean   :246.3   Mean   :0.1485   Mean   :0.5281   Mean   :149.6  
##  3rd Qu.:274.5   3rd Qu.:0.0000   3rd Qu.:1.0000   3rd Qu.:166.0  
##  Max.   :564.0   Max.   :1.0000   Max.   :2.0000   Max.   :202.0  
##      exang           oldpeak         slope             ca        
##  Min.   :0.0000   Min.   :0.00   Min.   :0.000   Min.   :0.0000  
##  1st Qu.:0.0000   1st Qu.:0.00   1st Qu.:1.000   1st Qu.:0.0000  
##  Median :0.0000   Median :0.80   Median :1.000   Median :0.0000  
##  Mean   :0.3267   Mean   :1.04   Mean   :1.399   Mean   :0.7294  
##  3rd Qu.:1.0000   3rd Qu.:1.60   3rd Qu.:2.000   3rd Qu.:1.0000  
##  Max.   :1.0000   Max.   :6.20   Max.   :2.000   Max.   :4.0000  
##       thal           target      
##  Min.   :0.000   Min.   :0.0000  
##  1st Qu.:2.000   1st Qu.:0.0000  
##  Median :2.000   Median :1.0000  
##  Mean   :2.314   Mean   :0.5446  
##  3rd Qu.:3.000   3rd Qu.:1.0000  
##  Max.   :3.000   Max.   :1.0000

1a. Pengecekan dan Pembersihan Data

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
sum(duplicated(data))
## [1] 1
data <- data[!duplicated(data), ]
check_outliers <- function(x) {
  Q1 <- quantile(x, 0.25)
  Q3 <- quantile(x, 0.75)
  IQR <- Q3 - Q1
  lower <- Q1 - 1.5 * IQR
  upper <- Q3 + 1.5 * IQR
  sum(x < lower | x > upper)
}

sapply(data[, sapply(data, is.numeric)], check_outliers)
##      age      sex       cp trestbps     chol      fbs  restecg  thalach 
##        0        0        0        9        5       45        0        1 
##    exang  oldpeak    slope       ca     thal   target 
##        0        5        0       24        2        0
summary(data[, sapply(data, is.numeric)])
##       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.000   Min.   :0.000   Min.   :0.0000  
##  1st Qu.:0.0000   1st Qu.:0.000   1st Qu.:1.000   1st Qu.:0.0000  
##  Median :0.0000   Median :0.800   Median :1.000   Median :0.0000  
##  Mean   :0.3278   Mean   :1.043   Mean   :1.397   Mean   :0.7185  
##  3rd Qu.:1.0000   3rd Qu.:1.600   3rd Qu.:2.000   3rd Qu.:1.0000  
##  Max.   :1.0000   Max.   :6.200   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

Interpretasi 1a:
Data tidak memiliki nilai kosong (NA). Terdapat beberapa baris duplikat yang berhasil dihapus. Beberapa kolom numerik memiliki nilai ekstrim (outlier), namun karena konteks medis, outlier dianggap relevan dan tetap disertakan dalam analisis.

Mengapa Menggunakan Penanganan in== - Duplikat dihapus karena bisa menyebabkan bias (pengulangan observasi yang sama).
- Outlier tidak dihapus karena dalam data medis, nilai ekstrem bisa mencerminkan kondisi nyata pasien (misalnya pasien kritis atau tekanan darah ekstrem).
- Karena tidak ada missing values, tidak dilakukan imputasi atau penghapusan baris. Data tidak memiliki nilai kosong (NA). Terdapat beberapa baris duplikat yang berhasil dihapus. Beberapa kolom numerik memiliki nilai ekstrim (outlier), namun karena konteks medis, outlier dianggap relevan dan tetap disertakan dalam analisis.

1b. Visualisasi Gender, Usia, dan FBS

data$sex <- factor(data$sex, labels = c("Female", "Male"))

ggplot(data, aes(x=sex, fill=factor(target))) +
  geom_bar(position="dodge", color="black") +
  labs(title="Heart Disease by Sex", fill="Heart Disease")

ggplot(data[data$target == 1, ], aes(x=age)) +
  geom_histogram(binwidth=5, fill="salmon", color="black") +
  labs(title="Age Distribution - With Heart Disease")

ggplot(data[data$fbs == 1, ], aes(x=age)) +
  geom_histogram(binwidth=5, fill="orange", color="black") +
  labs(title="Age with Fasting Blood Sugar > 120")

Interpretasi 1b:
Laki-laki lebih banyak menderita penyakit jantung. Rentang usia 50–60 tahun merupakan yang paling sering terdiagnosis. Gula darah tinggi (>120 mg/dl) paling banyak ditemukan pada usia 55–65 tahun.

1c. Analisis FBS > 120

table_fbs <- table(data$fbs, data$target)
prop.table(table_fbs, 1) * 100
##    
##            0        1
##   0 45.13619 54.86381
##   1 48.88889 51.11111
data$fbs <- factor(data$fbs, labels = c("<= 120", "> 120"))

ggplot(data, aes(x=fbs, fill=factor(target))) +
  geom_bar(position="fill", color="black") +
  scale_y_continuous(labels=scales::percent) +
  labs(title="Heart Disease by Fasting Blood Sugar", y="Proportion", fill="Heart Disease")

Interpretasi 1c:
Hasil visualisasi menunjukkan bahwa penderita dengan kadar gula darah lebih dari 120 mg/dL memiliki proporsi penyakit jantung yang lebih tinggi dibandingkan dengan kelompok kadar gula darah normal. Meskipun perbedaannya tidak terlalu mencolok, temuan ini tetap menguatkan bahwa kadar gula darah merupakan salah satu indikator yang perlu diperhatikan dalam mengidentifikasi risiko penyakit jantung.

1d. Chest Pain Type pada Penderita Heart Disease

ggplot(data[data$target == 1, ], aes(x=factor(cp))) +
  geom_bar(fill="steelblue", color="black") +
  labs(title="Chest Pain Type among Heart Disease Patients", x="Chest Pain Type")

Interpretasi 1d:
Grafik menunjukkan distribusi jenis nyeri dada (chest pain type) pada pasien yang menderita penyakit jantung (target == 1). Dari hasil visualisasi, tipe nyeri dada yang paling sering dialami oleh penderita penyakit jantung adalah tipe 0 dan tipe 2. Ini menunjukkan bahwa tipe nyeri dada tertentu (terutama tipe 0 = typical angina dan tipe 2 = non-anginal pain) dapat menjadi gejala umum atau indikator awal penyakit jantung.

1e. Bar Plot Proporsi Kategorikal

cat_vars <- c("cp", "ca", "thal")
for (var in cat_vars) {
  print(
    ggplot(data, aes_string(x=var, fill="factor(target)")) +
      geom_bar(position="fill", color="black") +
      scale_y_continuous(labels=scales::percent) +
      labs(title=paste("Heart Disease Proportion by", var), fill="Heart Disease") +
      theme_minimal()
  )
}
## Warning: `aes_string()` was deprecated in ggplot2 3.0.0.
## ℹ Please use tidy evaluation idioms with `aes()`.
## ℹ See also `vignette("ggplot2-in-packages")` for more information.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Interpretasi 1e:
Variabel cp, ca, dan thal menunjukkan perbedaan proporsi signifikan antara penderita dan non-penderita. Ini menunjukkan bahwa ketiganya penting dalam prediksi penyakit jantung.

1f. Hubungan Age dan Thalach

# Ubah label target jadi faktor dengan nama yang jelas
data$target <- factor(data$target, labels = c("Sehat", "Sakit"))

# Plot hubungan antara age dan thalach berdasarkan status penyakit
ggplot(data, aes(x = age, y = thalach, color = target)) +
  geom_point(shape = 21, fill = "white", color = "black") +
  geom_smooth(method = "loess", se = FALSE) +
  labs(
    title = "Hubungan Usia dan Detak Jantung Maksimum",
    x = "Usia",
    y = "Thalach (Detak Jantung Maksimum)",
    color = "Status"
  )
## `geom_smooth()` using formula = 'y ~ x'

Interpretasi 1f:
Plot menunjukkan hubungan antara usia dan detak jantung maksimum (thalach) berdasarkan status kesehatan (target). Secara umum, terlihat bahwa detak jantung maksimum cenderung menurun seiring bertambahnya usia, baik pada penderita penyakit jantung maupun individu yang sehat. Namun, penderita penyakit jantung cenderung memiliki nilai thalach yang lebih rendah dibandingkan kelompok sehat pada rentang usia yang sama. Pola ini menunjukkan bahwa detak jantung maksimum yang lebih rendah bisa menjadi indikasi adanya penyakit jantung, terutama pada usia lanjut.

1g. Heatmap Korelasi

num_df <- data %>% select_if(is.numeric)
corr <- round(cor(num_df), 2)

ggcorrplot(corr, 
           hc.order = TRUE, 
           type = "lower", 
           lab = TRUE,
           lab_size = 3,     # Ukuran label diperkecil
           colors = c("blue", "white", "red"))

Interpretasi 1g:
Plot korelasi menunjukkan hubungan antar variabel numerik dalam data. Warna merah mengindikasikan korelasi positif, sedangkan biru menunjukkan korelasi negatif,semakin kuat warnanya, semakin kuat hubungannya. Dari plot terlihat bahwa beberapa variabel memiliki hubungan yang cukup kuat, baik positif maupun negatif. Contohnya, thalach cenderung berkorelasi negatif dengan age, artinya semakin tua usia, detak jantung maksimum biasanya semakin rendah. Korelasi semacam ini bisa membantu dalam memahami pola data dan memilih variabel penting untuk analisis lebih lanjut.

# 1h. Summary Analisis

Insight:

Pencegahan:

### **2. Melakukan Visualisasi menggunakan data**

# 1. Input Data
data <- data.frame(
  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))
)

# 2. Visualisasi dengan ggplot2 + garis regresi
library(ggplot2)

ggplot(data, aes(x = Konsumsi_GWh, y = Biaya_per_kWh, color = Konsumen)) +
  geom_point(size = 3) +
  geom_smooth(method = "lm", se = FALSE, linewidth = 1) +  # Tambahan garis linear per grup
  labs(
    title = "Hubungan Konsumsi Listrik dan Biaya per kWh",
    x = "Konsumsi (GWh)",
    y = "Biaya per kWh (Rp)"
  ) +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

Penjelasan Sintaks:
- data.frame(…): Membuat tabel data dengan tiga kolom: Konsumsi, Biaya, dan Jenis Konsumen.
- rep(…): Mengulang nama jenis konsumen sesuai banyaknya data masing-masing kategori.
- library(ggplot2): Memanggil package ggplot2 untuk visualisasi.
- ggplot(data, aes(…)): Membuat objek grafik dari data dengan estetika dasar: x = Konsumsi_GWh: sumbu x adalah konsumsi energi. y = Biaya_per_kWh: sumbu y adalah biaya.
- color = Konsumen: membedakan warna berdasarkan jenis konsumen.
- geom_point(size = 3): Membuat titik-titik berukuran 3.
- labs(…): Menambahkan judul dan label sumbu.
- theme_minimal(): Menggunakan tema bersih dan minimal.
- geom_smooth(method = “lm”, se = FALSE): Menambahkan garis regresi linear tanpa area standar deviasi.
Interpretasi
-Grafik hubungan antara konsumsi listrik (GWh) dan biaya per kWh pada berbagai kelompok konsumen menunjukkan pola yang konsisten, di mana peningkatan konsumsi listrik umumnya diikuti oleh penurunan tarif per kWh.

-Pada segmen rumah tangga, konsumen dengan tingkat pemakaian listrik yang lebih tinggi cenderung mendapatkan tarif per kWh yang lebih rendah dibandingkan mereka yang konsumsi listriknya lebih sedikit.

-Pola serupa juga tampak pada sektor industri, di mana perusahaan dengan konsumsi listrik besar biasanya menikmati tarif yang lebih rendah. Kondisi ini bisa menjadi indikasi adanya kebijakan tarif khusus atau insentif yang ditujukan untuk mendukung kegiatan produksi dan efisiensi di sektor industri.

-Segmen kantor pemerintahan memperlihatkan kecenderungan yang sejalan, walaupun jumlah data pada kelompok ini relatif lebih sedikit, sehingga interpretasi hasilnya perlu dilakukan dengan hati-hati.

-Di sisi lain, UMKM juga menunjukkan pola bahwa semakin besar konsumsi listrik, semakin rendah biaya per kWh yang dikeluarkan. Hal ini bisa mencerminkan adanya kebijakan dukungan tarif bagi pelaku usaha skala kecil.

-Secara keseluruhan, visualisasi ini menunjukkan hubungan negatif antara konsumsi listrik dan tarif per kWh di seluruh segmen konsumen, yang merefleksikan penerapan skema tarif berbasis volume pemakaian. Meski sistem ini memberikan keuntungan bagi konsumen dengan penggunaan besar, dampak terhadap efisiensi energi dan keadilan antar kelompok pengguna tetap menjadi pertimbangan penting. ```