data_heart <- read.csv("C:/Users/USER/Downloads/heart.csv")
head (data_heart)
## age sex cp trestbps chol fbs restecg thalach exang oldpeak slope ca thal
## 1 63 1 3 145 233 1 0 150 0 2.3 0 0 1
## 2 37 1 2 130 250 0 1 187 0 3.5 0 0 2
## 3 41 0 1 130 204 0 0 172 0 1.4 2 0 2
## 4 56 1 1 120 236 0 1 178 0 0.8 2 0 2
## 5 57 0 0 120 354 0 1 163 1 0.6 2 0 2
## 6 57 1 0 140 192 0 1 148 0 0.4 1 0 1
## target
## 1 1
## 2 1
## 3 1
## 4 1
## 5 1
## 6 1
str(data_heart)
## '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 ...
colSums(is.na(data_heart))
## 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
Tidak terdapat Missing Values pada data Heart Disease.
#Data Ganda
sum(duplicated(data_heart))
## [1] 1
Terdapat 1 data yang tercatat ganda.
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)
}
# Terapkan fungsi ke kolom numerik
sapply(data_heart[, sapply(data_heart, 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 25 2 0
Hasilnya menunjukkan bahwa variabel fbs memiliki jumlah outlier terbanyak, yaitu sebanyak 45 nilai. Disusul oleh variabel ca dengan 25 outlier, trestbps dengan 9 outlier, serta chol dan oldpeak masing-masing dengan 5 outlier. Sementara itu, variabel thalach dan thal memiliki 1 dan 2 outlier secara berturut-turut. Adapun variabel age, cp, restecg, exang, dan slope tidak memiliki outlier sama sekali. Ini menunjukkan bahwa beberapa variabel dalam dataset memiliki distribusi data yang lebih stabil.
Karena terdapat data yang duplikat, maka penanganan yang tepat pada data ini adalah melakukan penghapusan data duplikat.
#Menghapus data ganda
data_heart <- data_heart[!duplicated(data_heart), ]
Sehingga didapatkan statistika deskriptif setelah penghapusan data
duplikat.
- Statistik Deskriptif.
summary(data_heart[, sapply(data_heart, 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
library(ggplot2)
#Konversi kolom sex & target menjadi faktor
data_heart$sex <- factor(data_heart$sex, labels = c("Female", "Male"))
data_heart$target <- factor(data_heart$target, labels = c("No Disease", "Disease"))
#Visualisasi jenis kelamin yang paling banyak mengalami heart disease.
ggplot(data_heart[data_heart$target == "Disease", ], aes(x = sex)) +
geom_bar(fill = "#e4cab5") +
labs(title = "Jenis Kelamin yang Mengalami Heart Disease", x = "Jenis Kelamin", y = "Jumlah") +
theme_minimal()
Dapat dilihat dari visualisasi diatas yang menunjukkan bahwa jenis kelamin pria yang mengalami Heart Disease
#Visualisasi usia yang paling banyak mengalami heart disease.
ggplot(data_heart[data_heart$target == "Disease", ], aes(x = age)) +
geom_histogram(binwidth = 1, fill = "#D2E0D3", color = "black") +
labs(title = "Distribusi Usia Pasien dengan Heart Disease", x = "Usia", y = "Jumlah") +
theme_minimal()
Dari histogram tersebut dapat dilihat bahwa usia 54 tahun merupakan
usia yang paling banyak mengalami Heart Disease.
- Usia yang memiliki gula darah lebih besar dari >120 mg/dl.
#Visualisasi usia yang memiliki gula darah yang lebih besar daripada 120 mg/dl.
ggplot(data_heart[data_heart$fbs == 1, ], aes(x = age)) +
geom_histogram(binwidth = 1, fill = "#f2dfd3", color = "black") +
labs(title = "Distribusi Usia dengan Gula Darah > 120 mg/dl", x = "Usia", y = "Jumlah") +
theme_minimal()
Dari histogram diatas dapat dilihat bahwa usia paling banyak dengan gula darah yang lebih besar daripada 120 mg/dl berada di usia 52 tahun.
data_heart$fbs <- factor(data_heart$fbs, labels = c("≤120 mg/dl", ">120 mg/dl"))
data_heart$target <- factor(data_heart$target, labels = c("Tidak", "Ya"))
table_fbs_hd <- table(data_heart$fbs, data_heart$target)
table_fbs_hd
##
## Tidak Ya
## ≤120 mg/dl 116 141
## >120 mg/dl 22 23
ggplot(data_heart, aes(x = fbs, fill = target)) +
geom_bar(position = "fill", color = "black") +
labs(title = "Proporsi Heart Disease berdasarkan Gula Darah",
x = "Fasting Blood Sugar",
y = "Proporsi",
fill = "Heart Disease") +
scale_fill_manual(values = c("Tidak" = "#97B3AE", "Ya" = "#D2E0D3")) +
theme_minimal()
Bar Chart menunjukkan bahwa proporsi penderita dan non-penderita
penyakit jantung hampir sama pada kedua kategori gula darah puasa (≤120
mg/dl dan >120 mg/dl). Ini menunjukkan bahwa kadar gula darah puasa
tidak menunjukkan hubungan yang jelas dengan keberadaan penyakit jantung
dalam data ini.
data_heart$cp <- factor(data_heart$cp,
levels = 0:3,
labels = c("Typical Angina", "Atypical Angina", "Non-anginal Pain", "Asymptomatic"))
#Filter data penderita heart disease
penderita_hd <- subset(data_heart, target == "Ya")
#Buat tabel frekuensi jenis nyeri dada
table_cp <- table(penderita_hd$cp)
#Visualisasi
ggplot(penderita_hd, aes(x = cp)) +
geom_bar(fill = "#97B3AE", color = "black") +
labs(title = "Jenis Nyeri Dada pada Penderita Heart Disease",
x = "Jenis Nyeri Dada",
y = "Jumlah") +
theme_minimal()
Berdasarkan visualisasi diatas, jenis nyeri dada paling umum yang dialami oleh penderita penyakit jantung adalah Non-anginal Pain (nyeri dada non-angina), dengan jumlah kasus tertinggi dibandingkan jenis lainnya. Selanjutnya oleh Atypical Angina dan Typical Angina yang jumlahnya relatif seimbang. Sementara itu, jenis Asymptomatic (tidak menunjukkan gejala nyeri dada) merupakan yang paling jarang terjadi. Hal ini menunjukkan bahwa sebagian besar penderita penyakit jantung dalam dataset mengalami nyeri dada yang tidak khas, bukan nyeri khas angina atau tidak menunjukkan gejala sama sekali.
# cp (jenis nyeri dada)
ggplot(data_heart, aes(x = factor(cp), fill = factor(target))) +
geom_bar(position = "fill") +
scale_fill_manual(
values = c("#97B3AE", "#D2E0D3")) +
labs(x = "Jenis Nyeri Dada", y = "Proporsi", fill = "Penyakit Jantung")
Dapat diketahui bahwa pasien dengan cp = 2 (Non-anginal pain) dan cp = 1 (Atypical angina) memiliki proporsi tertinggi menderita penyakit jantung dan cp = 0 (Typical angina) memiliki proporsi lebih rendah terhadap penyakit jantung.
# ca (jumlah pembuluh darah besar)
ggplot(data_heart, aes(x = factor(ca), fill = factor(target))) +
geom_bar(position = "fill") +
scale_fill_manual(
values = c("#97B3AE", "#D2E0D3")) +
labs(x = "Jumlah Pembuluh Besar", y = "Proporsi", fill = "Penyakit Jantung")
Dapat diketahui bahwa semakin banyak pembuluh darah yang terlihat (ca > 0), proporsi penderita jantung justru lebih rendah dan ca = 0 memiliki proporsi tertinggi menderita penyakit jantung.
# thal
ggplot(data_heart, aes(x = factor(thal), fill = factor(target))) +
geom_bar(position = "fill") +
scale_fill_manual(
values = c("#97B3AE", "#D2E0D3")) +
labs(x = "Jenis Thal", y = "Proporsi", fill = "Penyakit Jantung")
Dapat diketahui bahwa kategori thal = 2 (fixed defect) dan thal = 3 (reversible defect) menunjukkan proporsi tinggi penderita penyakit jantung dan thal = 1 (normal) memiliki proporsi rendah.
library(ggplot2)
ggplot(data_heart, aes(x = age, y = thalach, color = as.factor(target))) +
geom_point(alpha = 0.6) +
geom_smooth(method = "lm", se = FALSE) +
labs(
title = "Hubungan antara Age dan Thalach berdasarkan Status Penyakit Jantung",
x = "Usia",
y = "Detak Jantung Maksimum (thalach)",
color = "Status"
) +
scale_color_manual(labels = c("Tidak Sakit", "Sakit"), values = c("#97B3AE", "#D2E0D3")) +
theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'
Dari visualisasi tersebut dapat dilihat bahwa terdapat arah negatif antara usia dan thalach yang dimana semakin tua usia, cenderung semakin rendah detak jantung maksimum, terutama pada kelompok yang memiliki penyakit jantung. Garis non-linear terlihat lebih mengikuti pola data dibandingkan dengan garis linear, terutama pada kelompok penderita penyakit jantung. Hal ini menunjukkan bahwa hubungan antara age dan thalach cenderung non-linear, terdapat pola yang tidak bisa dijelaskan dengan regresi linear.
# Korelasi
numeric_data <- data_heart[, sapply(data_heart, is.numeric)]
cor_matrix <- cor(numeric_data)
# Heatmap
library(corrplot)
## Warning: package 'corrplot' was built under R version 4.3.3
## corrplot 0.95 loaded
corrplot(cor_matrix, method = "color", type = "upper", tl.cex = 0.8)
Berdasarkan heatmap di atas, terlihat bahwa sebagian besar variabel memiliki korelasi yang rendah satu sama lain yang ditunjukkan oleh warna yang mendekati putih. Namun, ada beberapa hubungan yang cukup mencolok, seperti korelasi negatif antara thalach (detak jantung maksimal) dan age, serta antara exang (angina akibat olahraga) dengan thalach, yang ditunjukkan dengan warna biru muda ke merah muda. Sementara itu, variabel oldpeak memiliki korelasi negatif yang cukup kuat dengan slope, dan korelasi positif sedang dengan exang. Korelasi paling kuat (positif maupun negatif) tampaknya tidak mendekati ±1, yang menandakan tidak ada multikolinearitas yang ekstrem di antara variabel-variabel tersebut.
Berikut Pencegahannya :
- Mulai rutin cek tekanan darah, kolesterol, dan gula darah baik melalui
puskesmas ataupun rumah sakit.
- Menerapkan pola hidup sehat dan aktif secara fisik seperti
berolahraga.
- Melakukan pemeriksaan kesehatan jantung secara berkala.
# Load library
library(ggplot2)
library(scales)
## Warning: package 'scales' was built under R version 4.3.3
# Membuat 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 = factor(c(
rep("Rumah Tangga", 6),
rep("Industri", 6),
rep("Kantor Pemerintah", 5),
rep("UMKM", 7)
))
)
# Membuat grafik
ggplot(data, aes(x = Konsumsi_GWh, y = Biaya_per_kWh, color = Konsumen)) +
geom_point(size = 3) +
geom_smooth(method = "lm", se = FALSE) +
labs(
title = "Biaya Listrik per kWh Menurun Seiring Kenaikan Konsumsi",
x = "Total Konsumsi Listrik (GWh)",
y = "Biaya per kWh (Rupiah)",
caption = "Data simulasi untuk keperluan edukasi"
) +
scale_y_continuous(labels = label_number(suffix = " Rp", big.mark = ".", decimal.mark = ",")) +
scale_x_log10(
breaks = c(10, 30, 100, 300), # Atur titik X seperti contoh
labels = label_number(big.mark = ".", decimal.mark = ",")
) +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, size = 14, face = "bold"),
axis.title.x = element_text(size = 12),
axis.title.y = element_text(size = 12),
plot.caption = element_text(hjust = 1, size = 8, face = "italic"),
legend.title = element_blank()
)
## `geom_smooth()` using formula = 'y ~ x'
Library library(ggplot2) → Untuk membuat grafik. library(scales) → Untuk memformat angka (misal menambah “Rp” di Y-axis).
Data data.frame(…) → Membuat tabel data berisi: Konsumsi_GWh: konsumsi listrik (sumbu X). Biaya_per_kWh: biaya listrik per kWh (sumbu Y). Konsumen: jenis konsumen (untuk membedakan warna titik).
Grafik Dasar ggplot(data, aes(x = …, y = …, color = …)) → Menentukan data apa yang diplot: x: konsumsi listrik. y: biaya listrik. color: membedakan jenis konsumen.
Elemen Grafik geom_point(size = 3) → Menambahkan titik-titik data, ukuran 3. geom_smooth(method = “lm”, se = FALSE) → Menambahkan garis trend (regresi linear), tanpa area bayangan.
Judul dan Label labs(title = …, x = …, y = …, caption = …) → Menambahkan: Judul grafik. Nama sumbu X. Nama sumbu Y. Keterangan/caption di bawah grafik.
Format Sumbu Y scale_y_continuous(labels = label_number(suffix = ” Rp”, big.mark = “.”, decimal.mark = “,”)) → Format angka Y-axis. Tambahkan satuan “Rp”. Gunakan titik (.) untuk pemisah ribuan.
Format Sumbu X (Log Skala) scale_x_log10(breaks = c(10, 30, 100, 300)) → Gunakan skala logaritmik di X. Tentukan titik angka di X: 10, 30, 100, 300.
Tema Grafik theme_minimal() → Menggunakan tema minimalis untuk grafik. theme(…) → Pengaturan tambahan: plot.title: posisi dan ukuran judul. axis.title.x/y: ukuran teks judul sumbu. plot.caption: posisi dan gaya caption. legend.title = element_blank(): menghilangkan judul legenda.
Grafik menunjukkan bahwa biaya listrik per kWh menurun seiring meningkatnya total konsumsi listrik, berdasarkan data simulasi untuk empat kategori: Industri, Kantor Pemerintah, Rumah Tangga, dan UMKM.
Sektor Industri memiliki konsumsi tertinggi dengan tarif per kWh terendah, sementara UMKM menunjukkan konsumsi paling rendah dan tarif tertinggi. Kantor Pemerintah dan Rumah Tangga berada di antara keduanya, mengikuti tren serupa.
Pola ini mencerminkan prinsip skala ekonomi, di mana pengguna dengan konsumsi besar mendapat tarif lebih murah. Ini bisa menjadi strategi tarif yang mendorong efisiensi atau mendukung sektor prioritas.