data<- read.csv("D:/Download/heartdata.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
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 ...
A. Cek dan Tangani Missing Value, Duplikat, Outlier + Stat Deskriptif
# Cek missing value per kolom
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 dan hapus duplikat
sum(duplicated(data))
## [1] 1
df_clean <- data[!duplicated(data), ]
# 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(df_clean[, sapply(df_clean, 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 24 2 0
# Statistik deskriptif kolom numerik
summary(df_clean[, sapply(df_clean, 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
B. Lakukan visualisasi untuk menunjukkan jenis kelamin apa yang paling banyak mengalami Heart desease, dan usia berapa yang paling banyak mengalami heart desease,dan usia berapa yang memiliki gula darah lebih besar dari 120 mg/dl.
library(ggplot2)
## Warning: package 'ggplot2' 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
# Ubah kolom kategori ke factor
df_clean$sex <- factor(df_clean$sex, levels = c(0,1), labels = c("Perempuan", "Laki-laki"))
df_clean$target <- factor(df_clean$target, levels = c(0,1), labels = c("Tidak", "Ya"))
# Visualisasi Usia yang Paling Banyak Mengalami Heart Disease
ggplot(df_clean %>% filter(target == "Ya"), aes(x = sex)) +
geom_bar(fill = "red", color = "black") +
labs(title = "Jenis Kelamin yang Mengalami Heart Disease",
x = "Jenis Kelamin", y = "Jumlah") +
theme_minimal()
# Visualisasi Usia Penderita Heart Disease
ggplot(df_clean %>% filter(target == "Ya"), aes(x = age)) +
geom_histogram(binwidth = 1, fill = "green", color = "black") +
labs(title = "Distribusi Usia Penderita Heart Disease",
x = "Usia", y = "Jumlah") +
theme_minimal()
# Visualisasi Usia dengan Kadar Gula Darah > 120 mg/dL
ggplot(df_clean %>% filter(fbs == 1), aes(x = age)) +
geom_histogram(binwidth = 1, fill = "blue", color = "black") +
labs(title = "Distribusi Usia dengan Gula Darah > 120 mg/dL",
x = "Usia", y = "Jumlah") +
theme_minimal()
C. Lakukan analisis untuk mengetahui, apakah kadar gula darah seseorang yang lebih besar dari 120 paling banyak mengalami Heart desease?
# Pastikan library dplyr dan ggplot2 sudah dimuat
library(dplyr)
library(ggplot2)
# Pastikan kembali target dalam bentuk karakter
df_clean <- df_clean %>%
mutate(
fbs_label = ifelse(fbs == 1, ">120 mg/dL", "<=120 mg/dL"),
target_label = ifelse(target == "Ya", "Heart Disease", "Tidak")
)
# Hitung jumlah kombinasi fbs dan target
fbs_heart_table <- df_clean %>%
group_by(fbs_label, target_label) %>%
summarise(jumlah = n(), .groups = "drop")
# Tampilkan tabel hasil
print(fbs_heart_table)
## # A tibble: 4 × 3
## fbs_label target_label jumlah
## <chr> <chr> <int>
## 1 <=120 mg/dL Heart Disease 141
## 2 <=120 mg/dL Tidak 116
## 3 >120 mg/dL Heart Disease 23
## 4 >120 mg/dL Tidak 22
# Visualisasi barplot
ggplot(fbs_heart_table, aes(x = fbs_label, y = jumlah, fill = target_label)) +
geom_bar(stat = "identity", position = position_dodge()) +
labs(title = "Distribusi Heart Disease Berdasarkan Kadar Gula Darah",
x = "Kadar Gula Darah", y = "Jumlah",
fill = "Status Penyakit") +
scale_fill_manual(values = c("Heart Disease" = "yellow", "Tidak" = "blue")) +
theme_minimal()
D. Lakukan identifikasi untuk mengetahui jenis nyeri dada yang paling banyak terjadi pada seseorang mengalami Heart desease
# Label untuk jenis nyeri dada (chest pain)
# 0 = Typical angina
# 1 = Atypical angina
# 2 = Non-anginal pain
# 3 = Asymptomatic
df_clean <- df_clean %>%
mutate(
cp_label = factor(cp,
levels = c(0, 1, 2, 3),
labels = c("Typical angina", "Atypical angina", "Non-anginal pain", "Asymptomatic"))
)
# Hitung jumlah masing-masing jenis nyeri dada pada penderita heart disease
chest_pain_count <- df_clean %>%
filter(target == "Ya") %>%
group_by(cp_label) %>%
summarise(jumlah = n(), .groups = 'drop') %>%
arrange(desc(jumlah))
# Tampilkan tabel
chest_pain_count
## # A tibble: 4 × 2
## cp_label jumlah
## <fct> <int>
## 1 Non-anginal pain 68
## 2 Atypical angina 41
## 3 Typical angina 39
## 4 Asymptomatic 16
# Visualisasi jenis nyeri dada pada penderita heart disease
ggplot(chest_pain_count, aes(x = reorder(cp_label, -jumlah), y = jumlah, fill = cp_label)) +
geom_bar(stat = "identity") +
labs(title = "Jenis Nyeri Dada pada Penderita Heart Disease",
x = "Jenis Nyeri Dada", y = "Jumlah") +
theme_minimal() +
theme(legend.position = "none")
E. Buat visualisasi Bar plot proporsi heart desease terhadap variabel kategorikal cp, ca, dan thal. Interpretasikan.
library(scales)
## Warning: package 'scales' was built under R version 4.4.3
# Label kategori cp sudah dibuat sebelumnya (cp_label), kita pakai ulang
# Ubah label faktor untuk ca dan thal agar lebih informatif
df_clean$ca <- factor(df_clean$ca,
levels = c(0, 1, 2, 3, 4),
labels = c("0", "1", "2", "3", "4"))
df_clean$thal <- factor(df_clean$thal,
levels = c(0, 1, 2),
labels = c("Normal", "Fixed Defect", "Reversible Defect"))
# Fungsi untuk membuat barplot proporsi
plot_proporsi <- function(var, title_var) {
ggplot(df_clean, aes_string(x = var, fill = "target")) +
geom_bar(position = "fill") +
scale_y_continuous(labels = percent) +
labs(title = paste("Proporsi Heart Disease berdasarkan", title_var),
x = title_var, y = "Proporsi", fill = "Heart Disease") +
scale_fill_manual(values = c("Tidak" = "blue", "Ya" = "yellow")) +
theme_minimal()
}
# Plot untuk cp, ca, dan thal
plot_proporsi("cp_label", "Jenis Nyeri Dada (cp)")
## 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.
Visualisasi proporsi penyakit jantung berdasarkan jenis nyeri dada (cp) nunjukin kalau kebanyakan orang yang punya penyakit jantung justru ada di kategori Asymptomatic, alias nggak ngerasa nyeri dada sama sekali. Artinya, meskipun kelihatannya sehat-sehat aja tanpa keluhan nyeri dada, mereka tetap bisa punya risiko tinggi kena penyakit jantung. Sebaliknya, orang yang ngerasa nyeri dada seperti Typical angina atau Atypical angina malah banyak yang nggak punya penyakit jantung. Mungkin aja nyeri dada yang mereka rasain itu bukan dari jantung, tapi dari hal lain seperti gangguan otot atau pencernaan..
plot_proporsi("ca", "Jumlah Pembuluh yang Diwarnai (ca)")
Dari variabel ca (jumlah pembuluh darah utama yang kelihatan lewat angiografi), keliatan kalau makin sedikit pembuluh darah yang kelihatan (kayak ca = 0), justru makin banyak orang yang punya penyakit jantung. Ini bisa jadi karena pembuluh darahnya tersumbat atau rusak, jadi nggak kelihatan di pemeriksaan, dan itu nunjukin risiko jantung yang lebih tinggi. Sebaliknya, kalau makin banyak pembuluh darah yang kelihatan (ca = 1 sampai 3), proporsi orang yang kena penyakit jantung justru lebih sedikit. Artinya, kondisi pembuluh darah mereka kemungkinan lebih bagus dan aliran darahnya lancar.
plot_proporsi("thal", "Hasil Tes Thalassemia (thal)")
Dari variabel thal (hasil tes thalassemia), ternyata orang dengan hasil Reversible Defect paling banyak yang punya penyakit jantung. Artinya, kalau hasil tes nunjukin ada gangguan yang muncul pas lagi tes stres, itu jadi tanda kuat ada masalah di jantung. Sebaliknya, kalau hasil tesnya Normal, proporsi yang kena penyakit jantung jauh lebih sedikit. Ini nunjukin kalau hasil thal yang normal biasanya berhubungan sama kondisi jantung yang sehat-sehat aja.
F. Lakukan eksplorasi untuk mengetahui arah hubungan antara variabel age dan thalach yang dibedakan untuk seseorang yang memiliki penyakit jantung dan tidak. Apakah hubungan itu linear atau non-linear? Bagaimana cara mengetahuinya?.
# Scatter plot biasa hubungan age vs thalach
# Scatter plot dengan garis tren linier
ggplot(df_clean, aes(x = age, y = thalach, color = target)) +
geom_point(alpha = 0.6) +
geom_smooth(method = "lm", se = FALSE) +
labs(title = "Hubungan antara Usia dan Denyut Jantung Maksimum (thalach)",
x = "Usia", y = "Thalach (detak jantung maksimum)",
color = "Heart Disease") +
theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'
Untuk ngelihat hubungan antara usia (age) dan detak jantung maksimum (thalach), dibuat scatter plot yang ditambahin garis tren lurus. Dari grafiknya keliatan, makin tua umur seseorang, biasanya detak jantung maksimalnya makin rendah. Jadi, ada hubungan negatif antara keduanya. Biar lebih yakin, dicek juga pakai analisis korelasi Pearson dan hasilnya memang nunjukin arah hubungan negatif. Artinya, makin nambah umur, makin turun juga detak jantung maksimalnya. Lalu dicek lagi pakai model regresi linier sederhana, dan hasilnya nunjukin kalau usia bener-bener punya pengaruh yang signifikan secara statistik — dan arahnya negatif. Jadi bisa disimpulkan, semakin tua seseorang, makin kecil kemungkinan dia punya detak jantung maksimum yang tinggi.
G. Buat heatmap korelasi antar variabel yang berskala interval atau rasio kemudian interpretasukan hasil yang didapat.
library(reshape2)
## Warning: package 'reshape2' was built under R version 4.4.3
# Ambil variabel numerik
numeric_vars <- df_clean %>%
select_if(is.numeric)
# Korelasi
cor_matrix <- cor(numeric_vars, use = "complete.obs")
# Visualisasi heatmap
ggplot(melt(cor_matrix), aes(Var1, Var2, fill = value)) +
geom_tile() +
scale_fill_gradient2(low = "orange", mid = "white", high = "pink", midpoint = 0) +
labs(title = "Heatmap Korelasi Antar Variabel Numerik",
x = "", y = "", fill = "Korelasi") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Heatmap ini nunjukin seberapa kuat hubungan antar variabel angka dalam data kesehatan jantung. Beberapa yang kelihatan jelas misalnya, detak jantung maksimum (thalach) punya hubungan negatif sama usia — artinya makin tua, detak jantung maksimalnya makin rendah. Terus, kemiringan ST (slope) juga berbanding terbalik dengan oldpeak, jadi kalau salah satu naik, yang lain cenderung turun. Selain itu, nyeri dada (cp) punya hubungan positif sama thalach (jadi makin parah nyeri dada, makin tinggi detak jantung maksimal), dan negatif sama exang (angina pas olahraga). Sementara variabel kayak fbs (kadar gula darah) dan restecg (hasil EKG istirahat) nggak terlalu nyambung sama variabel lain — artinya mereka punya pengaruh yang kecil atau bahkan nggak berkaitan langsung. Intinya, nggak semua variabel saling berhubungan kuat, jadi buat analisis atau model, kita bisa fokus ke variabel yang hubungannya memang kelihatan signifikan.
H. Buat summary hasil analisis yang telah dilakukan. Menurut kalian apa apa saja hal-hal yang dapat mencegah penyakit jantung dan aspek apa saja yang merupakan indikasi penyakit jantung.
Berdasarkan eksplorasi data kesehatan jantung yang dilakukan,
berikut ringkasan hasil analisis:
- Pembersihan Data: Tidak ditemukan nilai hilang, dan duplikat berhasil
dihapus. Beberapa outlier terdeteksi namun tidak langsung
dihilangkan.
- 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).
Pencegahan Penyakit Jantung Berdasarkan hasil di
atas, beberapa langkah pencegahan yang dapat diambil:
- Sering-sering cek kesehatan, termasuk tes thalassemia dan lihat
kondisi pembuluh darah, biar bisa tahu lebih awal kalau ada
masalah.
- Olahraga rutin itu penting supaya jantung tetap kuat dan detak jantung
maksimal (thalach) tetap bagus, apalagi kalau udah makin tua.
- Hati-hati walau nggak ngerasa sakit dada, soalnya banyak orang kena
penyakit jantung tapi nggak nunjukin gejala yang jelas.
- Tetap jaga tekanan darah, kolesterol, dan gaya hidup sehat, meskipun
gula darah kamu normal, karena semuanya tetap ngaruh ke kesehatan
jantung.
- Kelola stres dan makan yang sehat, itu juga kunci biar jantung kamu
tetap dalam kondisi prima.
Buat diagram yang sama dengan contoh. Serta jelaskan maksud setiap dari bagian sintax tersebut
# 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 (dalam GWh) dan biaya per kWh
nunjukin pola yang cukup jelas: makin besar pemakaian listrik, makin
murah biaya per kWh yang dibayar.
- Buat pelanggan rumah tangga, kelihatan kalau yang pakai listrik lebih
banyak justru bayar tarif lebih murah per kWh dibanding yang pakai
sedikit.
- Hal yang sama juga terjadi di sektor industri. Industri besar yang
konsumsi listriknya tinggi malah dapet tarif lebih murah, mungkin karena
ada kebijakan khusus atau insentif dari pemerintah biar industri tetap
jalan dan hemat energi.
- Di kantor pemerintahan, pola itu juga muncul, tapi karena datanya
nggak sebanyak yang lain, kita harus hati-hati buat ambil kesimpulan
pasti.
- UMKM juga nunjukin tren serupa makin besar konsumsi listriknya, makin
kecil biaya per kWh. Ini bisa jadi bentuk dukungan tarif buat usaha
kecil.
- Secara umum, grafik ini nunjukin ada hubungan terbalik antara
pemakaian listrik dan biaya per kWh di semua jenis pengguna. Artinya,
semakin banyak pakai listrik, semakin murah tarifnya. Tapi, kebijakan
kayak gini perlu juga dipikirin ulang biar tetap adil dan tetap
mendorong hemat energi di semua kalangan.