getwd()
## [1] "C:/Users/Hp/Downloads"
setwd("C:/R tugas")
data<- read.csv("C:/R tugas/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
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)
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.4.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
# 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 = "blue", 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 = "blue", 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 = "white") +
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" = "red", "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)
# 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" = "red")) +
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) menunjukkan bahwa sebagian besar penderita berada pada kategori Asymptomatic. Ini mengindikasikan bahwa meskipun tidak merasakan nyeri dada khas, risiko penyakit jantung tetap tinggi. Sebaliknya, nyeri dada seperti Typical atau Atypical angina justru lebih sering tidak terkait dengan penyakit jantung, kemungkinan karena penyebab lain di luar jantung.
plot_proporsi("ca", "Jumlah Pembuluh yang Diwarnai (ca)")
Visualisasi variabel ca (jumlah pembuluh darah utama yang terlihat pada angiografi) menunjukkan bahwa saat ca = 0, proporsi penderita penyakit jantung paling tinggi. Ini bisa mengindikasikan adanya penyumbatan atau kerusakan signifikan. Sebaliknya, semakin banyak pembuluh darah yang terlihat (ca = 1–3), proporsi penderita menurun, menandakan kondisi pembuluh darah yang lebih baik.
plot_proporsi("thal", "Hasil Tes Thalassemia (thal)")
Pada variabel thal (hasil tes thalassemia), kategori Reversible Defect menunjukkan proporsi penderita penyakit jantung tertinggi. Ini mengindikasikan bahwa defek reversibel saat tes stres merupakan indikator kuat adanya gangguan jantung. Sebaliknya, kategori Normal memiliki proporsi penderita jauh lebih rendah, mencerminkan kondisi jantung yang lebih sehat.
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 melihat hubungan antara usia (age) dan denyut jantung maksimum (thalach), digunakan scatter plot dengan garis tren linier. Hasilnya menunjukkan bahwa thalach cenderung menurun seiring bertambahnya usia, mengindikasikan hubungan negatif. Analisis korelasi Pearson dan regresi linier sederhana juga menunjukkan koefisien negatif yang signifikan, memperkuat kesimpulan bahwa usia berbanding terbalik dengan thalach.
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 = "black", mid = "white", high = "blue", 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 menunjukkan korelasi antar variabel numerik dalam data jantung. Terlihat korelasi negatif antara thalach dan age, serta antara slope dan oldpeak. Variabel cp berkorelasi positif dengan thalach dan negatif dengan exang. Sementara itu, fbs dan restecg memiliki korelasi lemah, menandakan tidak semua variabel saling berhubungan kuat atau signifikan dalam analisis.
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: Data tidak memiliki nilai hilang, dan duplikat telah
dihapus. Beberapa outlier terdeteksi, namun belum langsung dihapus dari
data.
- Jenis Kelamin: Penderita penyakit jantung lebih banyak ditemukan pada
laki-laki dibandingkan perempuan.
- Usia: Penyakit jantung paling banyak ditemui pada rentang usia 50–60
tahun, dengan kadar gula darah >120 mg/dL.
- Gula Darah: Sebagian besar penderita penyakit jantung memiliki kadar
gula darah ≤120 mg/dL, yang menunjukkan bahwa kadar gula tinggi bukanlah
faktor utama dalam dataset ini.
- Nyeri Dada (cp): Penderita penyakit jantung paling banyak terdapat
pada kategori Asymptomatic, yang menunjukkan bahwa meski tanpa gejala
nyeri dada khas, risiko penyakit tetap tinggi.
- Pembuluh Darah (ca): Semakin sedikit pembuluh darah yang terlihat,
terutama pada ca = 0, semakin tinggi proporsi penderita penyakit
jantung.
- Thalassemia (thal): Penderita penyakit jantung paling banyak ditemukan
pada kategori tes “Reversible Defect”.
- Hubungan Usia dan Thalach: Terdapat hubungan negatif yang jelas, di
mana semakin tua usia, semakin rendah denyut jantung maksimum.
- Heatmap Korelasi: Terdapat beberapa korelasi signifikan, seperti
antara usia dan thalach (negatif), serta antara cp dan thalach
(positif).
Pencegahan Penyakit Jantung Berdasarkan hasil di atas,
beberapa langkah pencegahan yang dapat diambil:
- Rutin melakukan cek kesehatan, termasuk tes thalassemia dan pengecekan
pembuluh darah, sangat penting untuk deteksi dini masalah
kesehatan.
- Menjaga kebugaran jantung dengan olahraga teratur penting agar thalach
tetap optimal, terutama seiring bertambahnya usia.
- Waspadai risiko meski tanpa gejala, karena banyak penderita penyakit
jantung yang tidak mengalami nyeri dada klasik.
- Pantau tekanan darah, kadar kolesterol, dan gaya hidup, meski kadar
gula darah normal.
- Manajemen stres dan pola makan sehat juga penting untuk menjaga
kesehatan jantung.
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
- Visualisasi menunjukkan bahwa semakin tinggi konsumsi listrik, semakin
rendah biaya per kWh yang dibayarkan, pola ini konsisten di berbagai
jenis konsumen.
- Pada segmen rumah tangga, pelanggan dengan konsumsi listrik tinggi
cenderung membayar tarif per kWh yang lebih rendah dibandingkan
pelanggan dengan konsumsi listrik rendah.
- Pola serupa juga terlihat pada sektor industri, di mana industri
dengan konsumsi besar mendapatkan tarif listrik lebih murah. Hal ini
mungkin mencerminkan kebijakan tarif khusus atau insentif pemerintah
untuk mendorong produksi dan efisiensi energi.
- Segmen kantor pemerintahan menunjukkan kecenderungan serupa, meskipun
jumlah data yang tersedia terbatas, sehingga perlu kehati-hatian dalam
menarik kesimpulan lebih lanjut.
- Pada UMKM, semakin tinggi konsumsi listrik, semakin rendah biaya per
kWh yang dibayar, yang mungkin mencerminkan adanya dukungan tarif bagi
pelaku usaha kecil.
- Secara keseluruhan, visualisasi menunjukkan korelasi negatif antara
konsumsi dan biaya per kWh di semua segmen, yang mencerminkan kebijakan
tarif berbasis volume konsumsi. Meskipun menguntungkan bagi konsumen
besar, perlu diperhatikan dampaknya terhadap efisiensi energi dan
keadilan tarif antar segmen pengguna.