#load libbrary
library(readr)
## Warning: package 'readr' was built under R version 4.4.3
library(dplyr)
##
## 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.4.3
library(reshape2)
## Warning: package 'reshape2' was built under R version 4.4.3
#import data
data <-read.csv("C:/Users/user/Downloads/heart.csv")
head(data)
## 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
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
#mengecek jumlah duplikat baris
sum(duplicated(data))
## [1] 1
data[duplicated(data),]
## age sex cp trestbps chol fbs restecg thalach exang oldpeak slope ca thal
## 165 38 1 2 138 175 0 1 173 0 0 2 4 2
## target
## 165 1
# Fungsi untuk mendeteksi outlier (metode IQR)
detect_outliers <- function(x) {
Q1 <- quantile(x, 0.25, na.rm = TRUE)
Q3 <- quantile(x, 0.75, na.rm = TRUE)
IQR <- Q3 - Q1
sum(x < (Q1 - 1.5 * IQR) | x > (Q3 + 1.5 * IQR))
}
# Hitung jumlah outlier pada setiap kolom numerik
outlier_counts <- sapply(data[, sapply(data, is.numeric)], detect_outliers)
# Tampilkan jumlah outlier
cat("\nJumlah outlier per kolom numerik:\n")
##
## Jumlah outlier per kolom numerik:
print(outlier_counts)
## 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
# Fungsi untuk mendeteksi outlier (metode IQR)
detect_outliers <- function(x) {
Q1 <- quantile(x, 0.25, na.rm = TRUE)
Q3 <- quantile(x, 0.75, na.rm = TRUE)
IQR <- Q3 - Q1
sum(x < (Q1 - 1.5 * IQR) | x > (Q3 + 1.5 * IQR))
}
# Hitung jumlah outlier pada setiap kolom numerik
outlier_counts <- sapply(data[, sapply(data, is.numeric)], detect_outliers)
# Tampilkan jumlah outlier
cat("\nJumlah outlier per kolom numerik:\n")
##
## Jumlah outlier per kolom numerik:
print(outlier_counts)
## 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
# Statistik deskriptif kolom numerik
summary(data[, sapply(data, is.numeric)])
## 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
# Pastikan kolom yang digunakan sesuai dengan struktur datamu.
# Biasanya: sex (0 = female, 1 = male), age, fbs (fasting blood sugar > 120 mg/dl, 1 = true), target (1 = heart disease)
# Jenis kelamin mana yang paling banyak mengalami heart disease
data %>%
group_by(sex) %>%
summarise(count = sum(target == 1)) %>%
ggplot(aes(x = factor(sex, labels = c("Female", "Male")), y = count, fill = factor(sex))) +
geom_col() +
labs(title = "Jumlah Penderita Heart Disease Berdasarkan Jenis Kelamin", x = "Jenis Kelamin", y = "Jumlah") +
theme_minimal()
# Usia berapa yang paling banyak mengalami heart disease
data %>%
filter(target == 1) %>%
ggplot(aes(x = age)) +
geom_histogram(binwidth = 3, fill = "darkblue", color = "black") +
labs(title = "Distribusi Usia Penderita Heart Disease", x = "Usia", y = "Jumlah") +
theme_minimal()
# Usia berapa yang memiliki gula darah > 120 mg/dl (fbs == 1)
data %>%
filter(fbs == 1) %>%
ggplot(aes(x = age)) +
geom_histogram(binwidth = 3, fill = "skyblue", color = "black") +
labs(title = "Distribusi Usia dengan Fasting Blood Sugar > 120 mg/dl", x = "Usia", y = "Jumlah") +
theme_minimal()
# Buat tabulasi antara fbs dan target
table_fbs_target <- table(data$fbs, data$target)
table_fbs_target
##
## 0 1
## 0 116 142
## 1 22 23
# Lakukan uji chi-square
chisq.test(table_fbs_target)
##
## Pearson's Chi-squared test with Yates' continuity correction
##
## data: table_fbs_target
## X-squared = 0.10627, df = 1, p-value = 0.7444
p-value < 0.05, maka ada hubungan signifikan antara kadar gula darah > 120 mg/dl dengan kejadian heart disease.
# Visualisasi chest pain type (cp) pada pasien yang mengalami heart disease
data %>%
filter(target == 1) %>%
count(cp) %>%
ggplot(aes(x = factor(cp), y = n, fill = factor(cp))) +
geom_col() +
labs(title = "Jenis Nyeri Dada (cp) pada Pasien dengan Heart Disease",
x = "Jenis Nyeri Dada (cp)", y = "Jumlah") +
theme_minimal()
# Fungsi bantu untuk barplot proporsi
plot_proporsi <- function(var){
data %>%
group_by({{var}}, target) %>%
summarise(count = n(), .groups = "drop") %>%
group_by({{var}}) %>%
mutate(proporsi = count / sum(count)) %>%
ggplot(aes(x = factor({{var}}), y = proporsi, fill = factor(target))) +
geom_col(position = "fill") +
labs(title = paste("Proporsi Heart Disease terhadap", deparse(substitute(var))),
x = deparse(substitute(var)),
y = "Proporsi", fill = "Heart Disease") +
theme_minimal()
}
plot_proporsi(cp)
Visualisasi proporsi heart disease berdasarkan variabel cp (jenis nyeri dada) menunjukkan bahwa sebagian besar penderita penyakit jantung berada pada kategori Asymptomatic (tidak merasakan nyeri dada). Hal ini menunjukkan bahwa seseorang yang tidak memiliki keluhan nyeri dada khas pun tetap berisiko tinggi mengidap penyakit jantung. Sebaliknya, mereka yang mengalami Typical angina atau Atypical angina justru cenderung tidak memiliki penyakit jantung, yang mungkin disebabkan oleh nyeri dada yang tidak berasal dari jantung.
plot_proporsi(ca)
variabel ca (jumlah pembuluh darah utama yang terlihat pada angiografi), terlihat bahwa semakin sedikit jumlah pembuluh darah yang terlihat (ca = 0), semakin besar proporsi penderita penyakit jantung. Hal ini dapat mengindikasikan bahwa tidak terlihatnya pembuluh darah bisa jadi menunjukkan adanya penyumbatan atau kerusakan yang signifikan, sehingga meningkatkan risiko penyakit jantung. Sebaliknya, semakin banyak pembuluh yang terlihat (ca = 1 hingga 3), proporsi penderita jantung menurun, menandakan kondisi pembuluh darah yang lebih baik
plot_proporsi(thal)
variabel thal (hasil tes thalassemia), ditemukan bahwa kategori Reversible Defect memiliki proporsi penderita heart disease yang paling tinggi. Hal ini menunjukkan bahwa defek reversibel—yang muncul saat tes stres—adalah indikator kuat adanya gangguan jantung. Sebaliknya, pada kategori Normal, proporsi penderita jantung jauh lebih rendah, menunjukkan bahwa hasil tes thal yang normal berhubungan erat dengan kondisi jantung yang sehat.
library(ggplot2)
library(dplyr)
# Visualisasi hubungan age vs thalach berdasarkan target
ggplot(data, aes(x = age, y = thalach, color = factor(target))) +
geom_point(alpha = 0.6) +
geom_smooth(method = "lm", se = FALSE) + # linear
geom_smooth(method = "loess", se = FALSE, linetype = "dashed") + # non-linear
labs(
title = "Hubungan antara Age dan Thalach",
x = "Umur",
y = "Thalach (Detak Jantung Maksimum)",
color = "Penyakit Jantung"
) +
theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'
## `geom_smooth()` using formula = 'y ~ x'
Secara umum, semakin tua usia, thalach cenderung menurun (baik pada
pasien dengan atau tanpa penyakit jantung). Pasien dengan penyakit
jantung (target = 1) cenderung memiliki nilai thalach yang lebih rendah
dibandingkan yang tidak sakit jantung.
Garis non-linear (loess) menunjukkan bahwa: -Penurunan thalach tidak
selalu linear. -Pada usia menengah, thalach mungkin tetap stabil atau
turun perlahan, tapi setelah usia tertentu bisa turun drastis.
numeric_vars <- data %>% select_if(is.numeric)
# Hitung matriks korelasi
cor_matrix <- cor(numeric_vars, use = "complete.obs")
# Ubah ke format long untuk visualisasi
cor_melted <- melt(cor_matrix)
# Plot heatmap
ggplot(cor_melted, aes(Var1, Var2, fill = value)) +
geom_tile() +
geom_text(aes(label = round(value, 2)), size = 3) +
scale_fill_gradient2(low = "blue", mid = "white", high = "red", midpoint = 0) +
labs(title = "Heatmap Korelasi Antar Variabel Numerik", fill = "Korelasi") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Heatmap tersebut menunjukkan korelasi antar variabel numerik dalam data kesehatan jantung. Beberapa korelasi yang menonjol adalah hubungan negatif antara thalach (detak jantung maksimum) dan age (usia), serta antara slope dan oldpeak, yang menunjukkan hubungan terbalik yang cukup kuat. Selain itu, cp (nyeri dada) berkorelasi positif dengan thalach dan negatif dengan exang (angina akibat olahraga). Sebaliknya, variabel seperti fbs dan restecg menunjukkan korelasi lemah atau hampir tidak ada dengan variabel lainnya. Hal ini menunjukkan bahwa tidak semua variabel memiliki hubungan yang signifikan dan beberapa bisa lebih berpengaruh dalam analisis atau pemodelan data.
Berdasarkan hasil analisis yang sudah dilakukan pada data di atas,
maka dapat ditarik kesimpulan berikut:
- Pemeriksaan awal dan pembersihan data: Data tersebut tidak memiliki
nilai hilang (missing value) setelah dilakukan pengecekan dan
pembersihan.
-Tidak ada data duplikat
-Outlier pada variabel numerik dapat diatasi dengan metode IQR.
- Jenis Kelamin: Laki-laki lebih banyak mengalami penyakit jantung
dibandingkan perempuan.
- Usia: Rentang usia sekitar 50–60 tahun paling banyak mengalami
penyakit jantung dan memiliki kadar gula darah >120 mg/dL.
- Gula Darah: Sebagian besar penderita penyakit jantung justru memiliki
kadar gula darah ≤120 mg/dL, artinya kadar gula tinggi bukan faktor
utama dalam dataset ini.
- Nyeri Dada (cp): Penderita heart disease paling banyak berada di
kategori Asymptomatic, menunjukkan bahwa meski tanpa gejala nyeri dada
khas, risiko tetap tinggi.
- Pembuluh Darah (ca): Semakin sedikit pembuluh darah yang terlihat
(terutama ca = 0), semakin tinggi proporsi penderita heart
disease.
- Thalassemia (thal): Hasil tes “Reversible Defect” paling banyak
dialami oleh penderita heart disease.
- Hubungan Usia dan Thalach: Terdapat hubungan negatif yang cukup
jelas—semakin tua usia, semakin rendah denyut jantung maksimum.
- Heatmap Korelasi: Terlihat beberapa korelasi signifikan, seperti
antara usia dan thalach (negatif), serta cp dan thalach (positif).
Beberapa langkah pencegahan penyakit jantung yang dapat
diambil:
- Rutin cek kesehatan, termasuk tes thalassemia dan pengecekan pembuluh
darah.
- Menjaga kebugaran jantung dengan olahraga teratur agar thalach tetap
optimal, terutama seiring bertambahnya usia.
- Waspadai risiko meski tanpa gejala: Banyak penderita tidak mengalami
nyeri dada klasik.
- Pantau tekanan darah, kadar kolesterol dan gaya hidup meski kadar gula
normal.
- Manajemen stres dan pola makan sehat juga penting untuk menjaga
kondisi jantung.
Input Data
data2 <- 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))
)
Visualisasi Data
ggplot(data2, 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)"
) +
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
- Visualisasi hubungan antara konsumsi listrik (dalam GWh) dan biaya per
kWh pada berbagai jenis konsumen menunjukkan pola yang konsisten, yaitu
semakin tinggi konsumsi listrik, semakin rendah biaya per kWh yang
dibayarkan.
- Pada segmen rumah tangga, terlihat bahwa pelanggan dengan konsumsi
listrik tinggi cenderung membayar tarif listrik per kWh yang lebih
rendah dibandingkan dengan pelanggan yang konsumsi listriknya
rendah.
- Pola serupa juga terlihat pada sektor industri, di mana industri
dengan konsumsi besar menikmati tarif listrik yang lebih murah. Hal ini
dapat mengindikasikan adanya kebijakan tarif khusus atau insentif dari
pemerintah bagi pelaku industri untuk mendorong produksi dan efisiensi
energi.
- Segmen kantor pemerintahan juga menunjukkan kecenderungan yang sama,
meskipun jumlah data yang tersedia tidak sebanyak segmen lainnya,
sehingga perlu kehati-hatian dalam menarik kesimpulan lebih
lanjut.
- Sementara itu, pada UMKM, terlihat bahwa semakin tinggi konsumsi
listrik, semakin rendah pula biaya per kWh yang harus dibayar, yang
dapat mencerminkan adanya dukungan tarif bagi pelaku usaha kecil.
- Secara keseluruhan, visualisasi ini menggambarkan adanya korelasi
negatif antara konsumsi dan biaya listrik per kWh di semua segmen
konsumen, yang mengindikasikan kebijakan tarif berbasis volume konsumsi.
Meskipun strategi ini menguntungkan bagi konsumen besar, perlu
dipertimbangkan dampaknya terhadap efisiensi energi dan keadilan tarif
antar segmen pengguna.