Berikut merupakan data yang digunakan pada soal, dan dibawah adalah kodingannya untuk mengimport data dengan menggunakan Rstudio:
library(readr)
heart <- read_csv("C:/Users/ASUS/OneDrive/Hardiven/Semester 4/Sains Data/UTS/heart.csv")
## Rows: 303 Columns: 14
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl (14): age, sex, cp, trestbps, chol, fbs, restecg, thalach, exang, oldpea...
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
heart
## # A tibble: 303 × 14
## age sex cp trestbps chol fbs restecg thalach exang oldpeak slope
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 63 1 3 145 233 1 0 150 0 2.3 0
## 2 37 1 2 130 250 0 1 187 0 3.5 0
## 3 41 0 1 130 204 0 0 172 0 1.4 2
## 4 56 1 1 120 236 0 1 178 0 0.8 2
## 5 57 0 0 120 354 0 1 163 1 0.6 2
## 6 57 1 0 140 192 0 1 148 0 0.4 1
## 7 56 0 1 140 294 0 0 153 0 1.3 1
## 8 44 1 1 120 263 0 1 173 0 0 2
## 9 52 1 2 172 199 1 1 162 0 0.5 2
## 10 57 1 2 150 168 0 1 174 0 1.6 2
## # ℹ 293 more rows
## # ℹ 3 more variables: ca <dbl>, thal <dbl>, target <dbl>
Dataset ini berisi data terkait kondisi kesehatan pasien untuk mendeteksi potensi penyakit jantung. Berikut adalah penjelasan masing-masing variabel beserta skala data yang digunakan:
| Nama Variabel | Deskripsi | Skala Data |
|---|---|---|
age |
Usia pasien dalam tahun | Rasio |
sex |
Jenis kelamin pasien (1 = laki-laki, 0 = perempuan) | Nominal |
cp |
Tipe nyeri dada (0 = typical angina, 1 = atypical angina, 2 = non-anginal pain, 3 = asymptomatic) | Ordinal |
trestbps |
Tekanan darah saat istirahat (dalam mm Hg) | Rasio |
chol |
Kadar kolesterol dalam darah (mg/dl) | Rasio |
fbs |
Gula darah puasa > 120 mg/dl (1 = ya, 0 = tidak) | Nominal |
restecg |
Hasil EKG saat istirahat (0 = normal, 1 = kelainan ST-T, 2 = hipertrofi ventrikel kiri) | Ordinal |
thalach |
Detak jantung maksimum yang dicapai | Rasio |
exang |
Apakah mengalami angina karena olahraga (1 = ya, 0 = tidak) | Nominal |
oldpeak |
Depresi ST yang diinduksi oleh olahraga terhadap kondisi istirahat | Rasio |
slope |
Kemiringan segmen ST saat latihan (0 = naik, 1 = datar, 2 = menurun) | Ordinal |
ca |
Jumlah pembuluh darah besar yang terdeteksi melalui fluoroskopi (0–3) | Rasio (Diskrit) |
thal |
Jenis thalassemia (1 = normal, 2 = cacat tetap, 3 = cacat reversibel) | Ordinal |
target |
Diagnosis penyakit jantung (1 = ada penyakit jantung, 0 = tidak ada) | Nominal |
colSums(is.na(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
Dari hasil percobaan pengecekan nilai yang hilang ditemukan tidak terdapat data yang hilang.
sum(duplicated(heart))
## [1] 1
heart <- heart[!duplicated(heart), ]
pada pengecekan data duplikat diperoleh bahwa terdapat 1 data yang terduplikat, dan dilakukan penanganan pada data tersebut dengan menghapus duplikat
# Fungsi untuk mengganti outlier dengan NA (menggunakan IQR)
replace_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
x[x < lower | x > upper] <- NA
return(x)
}
# Salin data untuk dibersihkan
heart_clean <- heart
# Terapkan ke kolom numerik
numeric_vars <- sapply(heart_clean, is.numeric)
heart_clean[, numeric_vars] <- lapply(heart_clean[, numeric_vars], replace_outliers)
# Imputasi outlier dengan median
heart_clean[, numeric_vars] <- lapply(heart_clean[, numeric_vars], function(x) {
x[is.na(x)] <- median(x, na.rm = TRUE)
return(x)
})
Penanganan: Outlier dapat mempengaruhi rata-rata dan analisis lainnya. Kita menggunakan metode IQR untuk mendeteksinya, dan menggantinya dengan median karena median tidak terpengaruh oleh nilai ekstrem.
summary(heart_clean[, numeric_vars])
## 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 :130.1
## 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. :170.0
## chol fbs restecg thalach exang
## Min. :126.0 Min. :0 Min. :0.0000 Min. : 88.0 Min. :0.0000
## 1st Qu.:211.0 1st Qu.:0 1st Qu.:0.0000 1st Qu.:134.5 1st Qu.:0.0000
## Median :240.0 Median :0 Median :1.0000 Median :153.0 Median :0.0000
## Mean :243.2 Mean :0 Mean :0.5265 Mean :149.8 Mean :0.3278
## 3rd Qu.:272.5 3rd Qu.:0 3rd Qu.:1.0000 3rd Qu.:166.0 3rd Qu.:1.0000
## Max. :360.0 Max. :0 Max. :2.0000 Max. :202.0 Max. :1.0000
## oldpeak slope ca thal
## Min. :0.0000 Min. :0.000 Min. :0.0000 Min. :1.000
## 1st Qu.:0.0000 1st Qu.:1.000 1st Qu.:0.0000 1st Qu.:2.000
## Median :0.7000 Median :1.000 Median :0.0000 Median :2.000
## Mean :0.9732 Mean :1.397 Mean :0.4669 Mean :2.328
## 3rd Qu.:1.6000 3rd Qu.:2.000 3rd Qu.:1.0000 3rd Qu.:3.000
## Max. :4.0000 Max. :2.000 Max. :2.0000 Max. :3.000
## target
## Min. :0.000
## 1st Qu.:0.000
## Median :1.000
## Mean :0.543
## 3rd Qu.:1.000
## Max. :1.000
Penjelasan:
Minimum dan maksimum menunjukkan rentang nilai.
Kuartil pertama, median, dan kuartil ketiga membantu memahami sebaran data.
Rata-rata menunjukkan nilai tengah secara umum setelah pembersihan.
Sebelum melakukan visualisasi, kita pastikan bahwa data sudah bersih dan siap untuk divisualisasikan.
library(ggplot2)
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
# Konversi label jenis kelamin
heart_clean$sex <- factor(heart_clean$sex, levels = c(0,1), labels = c("Perempuan", "Laki-laki"))
# Visualisasi
ggplot(heart_clean, aes(x = sex, fill = factor(target))) +
geom_bar(position = "dodge") +
labs(title = "Jumlah Penyakit Jantung berdasarkan Jenis Kelamin",
x = "Jenis Kelamin", y = "Jumlah",
fill = "Penyakit Jantung") +
scale_fill_manual(values = c("0" = "gray", "1" = "red"),
labels = c("Tidak", "Ya")) +
theme_minimal()
menunjukkan distribusi jumlah penderita penyakit jantung berdasarkan jenis kelamin. Jenis kelamin dengan batang merah lebih tinggi adalah yang paling banyak mengalaminya.
# Filter penderita heart disease
penderita_hd <- heart_clean %>% filter(target == 1)
# Histogram usia penderita
ggplot(penderita_hd, aes(x = age)) +
geom_histogram(binwidth = 2, fill = "red", color = "black") +
labs(title = "Distribusi Usia Penderita Penyakit Jantung",
x = "Usia", y = "Jumlah") +
theme_minimal()
Histogram ini menunjukkan pada usia berapa penderita penyakit jantung paling banyak ditemukan.
# Filter berdasarkan fbs > 120
gula_tinggi <- heart %>% filter(fbs == 1 )
# Histogram usia dengan fbs tinggi
ggplot(gula_tinggi, aes(x = age)) +
geom_histogram(binwidth = 2, fill = "steelblue", color = "black") +
labs(title = "Distribusi Usia dengan Gula Darah > 120 mg/dl",
x = "Usia", y = "Jumlah") +
theme_minimal()
Visualisasi ini menampilkan usia-usia yang sering mengalami gula darah puasa tinggi (>120 mg/dl) berada pada usia 53-54.
Tujuan dari analisis ini adalah untuk mengetahui apakah kadar gula darah > 120 mg/dl berhubungan dengan kemungkinan menderita penyakit jantung.
table_gula_hd <- table(heart$fbs, heart$target)
rownames(table_gula_hd) <- c("≤ 120 mg/dl", "> 120 mg/dl")
colnames(table_gula_hd) <- c("Tidak HD", "Penyakit Jantung")
table_gula_hd
##
## Tidak HD Penyakit Jantung
## ≤ 120 mg/dl 116 141
## > 120 mg/dl 22 23
# Hitung proporsi penderita heart disease pada masing-masing kelompok fbs
prop.table(table_gula_hd, margin = 1)
##
## Tidak HD Penyakit Jantung
## ≤ 120 mg/dl 0.4513619 0.5486381
## > 120 mg/dl 0.4888889 0.5111111
Interpretasi: Proporsi lebih tinggi pada kategori “> 120 mg/dl” menunjukkan bahwa orang dengan kadar gula darah tinggi memiliki kemungkinan lebih besar terkena penyakit jantung.
# Uji Chi-Square
chisq.test(table(heart_clean$fbs, heart_clean$target))
##
## Chi-squared test for given probabilities
##
## data: table(heart_clean$fbs, heart_clean$target)
## X-squared = 2.2384, df = 1, p-value = 0.1346
Penjelasan:
Jika nilai p-value < 0.05, maka ada hubungan signifikan antara fbs dan penyakit jantung.
Artinya, kadar gula darah > 120 berkorelasi signifikan dengan risiko penyakit jantung.
Tujuan analisis ini adalah mengetahui jenis nyeri dada apa yang
paling banyak dialami oleh pasien yang menderita penyakit jantung
(target = 1).
Visualisasi Frekuensi Nyeri Dada
library(dplyr)
library(ggplot2)
# Ubah kode chest pain menjadi label yang mudah dibaca
heart_clean$cp <- factor(heart_clean$cp,
levels = c(0, 1, 2, 3),
labels = c("Typical Angina", "Atypical Angina", "Non-anginal Pain", "Asymptomatic"))
# Filter hanya penderita penyakit jantung
penderita_hd <- heart_clean %>% filter(target == 1)
# Hitung frekuensi chest pain di antara penderita heart disease
library(ggplot2)
ggplot(penderita_hd, aes(x = cp)) +
geom_bar(fill = "tomato", color = "black") +
labs(title = "Jenis Nyeri Dada pada Penderita Penyakit Jantung",
x = "Jenis Nyeri Dada", y = "Jumlah") +
theme_minimal()
Tabel frekuensi chest pain pada penderita heart disease
table(penderita_hd$cp)
##
## Typical Angina Atypical Angina Non-anginal Pain Asymptomatic
## 39 41 68 16
Berdasarkan tabel frekuensi, jumlah masing-masing jenis nyeri dada pada penderita penyakit jantung adalah sebagai berikut:
Jenis nyeri dada yang paling sering dialami oleh penderita penyakit jantung adalah Non-anginal Pain, dengan total 68 kasus. Hal ini menunjukkan bahwa gejala nyeri dada yang tidak khas angina (non-anginal pain) dapat menjadi indikator yang penting untuk mendeteksi penyakit jantung.
Temuan ini juga menunjukkan bahwa tidak semua penderita heart disease mengalami nyeri dada yang “klasik”, sehingga penting bagi tenaga medis untuk mempertimbangkan variasi gejala saat melakukan diagnosis dini.
Kita akan memvisualisasikan proporsi penderita penyakit
jantung (target = 1) terhadap variabel kategorikal
cp, ca, dan thal.
# Ubah tipe data ke factor agar readable
heart_clean$cp <- factor(heart_clean$cp,
levels = c("Typical Angina", "Atypical Angina", "Non-anginal Pain", "Asymptomatic"))
heart_clean$ca <- factor(heart_clean$ca)
heart_clean$thal <- factor(heart_clean$thal)
# Buat proporsi target per kategori cp
heart_clean %>%
group_by(cp) %>%
summarise(prop_hd = mean(target)) %>%
ggplot(aes(x = cp, y = prop_hd)) +
geom_bar(stat = "identity", fill = "tomato", color = "black") +
labs(title = "Proporsi Penyakit Jantung berdasarkan Jenis Nyeri Dada",
x = "Jenis Nyeri Dada", y = "Proporsi Penderita Heart Disease") +
ylim(0,1) +
theme_minimal()
heart_clean %>%
group_by(ca) %>%
summarise(prop_hd = mean(target)) %>%
ggplot(aes(x = ca, y = prop_hd)) +
geom_bar(stat = "identity", fill = "skyblue", color = "black") +
labs(title = "Proporsi Penyakit Jantung berdasarkan Jumlah Pembuluh Darah (ca)",
x = "Jumlah ca", y = "Proporsi Penderita Heart Disease") +
ylim(0,1) +
theme_minimal()
heart_clean %>%
group_by(thal) %>%
summarise(prop_hd = mean(target)) %>%
ggplot(aes(x = thal, y = prop_hd)) +
geom_bar(stat = "identity", fill = "darkgreen", color = "black") +
labs(title = "Proporsi Penyakit Jantung berdasarkan Jenis Thalassemia",
x = "Thal", y = "Proporsi Penderita Heart Disease") +
ylim(0,1) +
theme_minimal()
Interpretasi Visualisasi: - Chest Pain (cp): - Proporsi tertinggi penderita penyakit jantung berada pada kategori Non-anginal Pain dan Asymptomatic, menunjukkan bahwa gejala nyeri dada bisa bersifat tidak khas pada pasien heart disease.
ca. Artinya, penderita dengan 0–1 pembuluh
lebih sering mengalami heart disease dibanding mereka dengan
ca lebih banyak (mungkin sebagai penanda kondisi pembuluh
lebih baik).thal = 2 jika itu mewakili reversible defect), menandakan
jenis thal tertentu bisa meningkatkan risiko penyakit
jantung.Visualisasi proporsi ini membantu memahami kategori mana yang lebih rentan terhadap penyakit jantung dan bisa dijadikan referensi untuk deteksi dini.
Tujuan bagian ini adalah mengeksplorasi hubungan antara usia
(age) dan detak jantung maksimum (thalach)
pada individu yang memiliki dan tidak memiliki penyakit jantung.
Visualisasi Scatter Plot dengan Garis Tren
library(ggplot2)
# Ubah target menjadi label
heart_clean$target <- factor(heart_clean$target,
levels = c(0, 1),
labels = c("Tidak Ada Penyakit Jantung", "Penyakit Jantung"))
# Scatter plot dengan garis regresi
ggplot(heart_clean, aes(x = age, y = thalach, color = target)) +
geom_point(alpha = 0.5) +
geom_smooth(method = "loess", se = FALSE, linetype = "dashed") +
labs(title = "Hubungan antara Usia dan Detak Jantung Maksimum",
x = "Usia", y = "Thalach (Detak Jantung Maksimum)") +
theme_minimal() +
scale_color_manual(values = c("steelblue", "tomato"))
## `geom_smooth()` using formula = 'y ~ x'
Korelasi dan Interpretasi Awal
# Hitung korelasi per grup target
library(dplyr)
heart_clean %>%
group_by(target) %>%
summarise(korelasi = cor(age, thalach))
## # A tibble: 2 × 2
## target korelasi
## <fct> <dbl>
## 1 Tidak Ada Penyakit Jantung -0.101
## 2 Penyakit Jantung -0.523
Interpretasi: - Arah hubungan:
Scatter plot menunjukkan bahwa semakin bertambah usia, nilai
thalach cenderung menurun, baik pada penderita maupun bukan
penderita penyakit jantung. Ini menunjukkan adanya hubungan
negatif antara usia dan detak jantung maksimum.
geom_smooth(method = "loess") untuk
menampilkan pola hubungan tanpa mengasumsikan linearitas.age dan
thalach negatif dan cenderung non-linear,
dengan penurunan detak jantung yang tidak selalu konstan terhadap
pertambahan usia.Visualisasi ini bertujuan untuk melihat kekuatan dan arah hubungan antar variabel numerik dalam data.
Membuat Heatmap Korelasi
# Ambil hanya variabel numerik
library(dplyr)
numeric_vars <- heart_clean %>%
select_if(is.numeric)
# Hitung korelasi
cor_matrix <- cor(numeric_vars)
## Warning in cor(numeric_vars): the standard deviation is zero
# Plot heatmap
library(ggplot2)
library(reshape2)
# Ubah ke format long
melted_cor <- melt(cor_matrix)
# Buat heatmap
ggplot(data = melted_cor, aes(x = Var1, y = Var2, fill = value)) +
geom_tile(color = "white") +
scale_fill_gradient2(low = "blue", high = "red", mid = "white",
midpoint = 0, limit = c(-1, 1), name = "Korelasi") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
labs(title = "Heatmap Korelasi Variabel Numerik",
x = "", y = "")
Interpretasi: Berdasarkan heatmap korelasi:
age memiliki korelasi negatif
yang cukup jelas dengan thalach, artinya semakin tua
seseorang, detak jantung maksimumnya cenderung menurun.trestbps dan chol cukup
lemah, menunjukkan tidak ada hubungan linier yang kuat antara tekanan
darah saat istirahat dan kolesterol.cp (jenis nyeri dada) mungkin memiliki korelasi sedang
dengan target, tetapi karena itu data kategorikal,
interpretasi korelasinya harus hati-hati.Penting dicatat: Korelasi tidak menunjukkan kausalitas. Meskipun dua variabel berkorelasi, bukan berarti yang satu menyebabkan yang lain.
library(readxl)
data2 <- read_excel("C:/Users/ASUS/OneDrive/Hardiven/Semester 4/Sains Data/UTS/Data2.xlsx")
ada bagian tersebut kodingan tersebut berfungsi untuk mengimpor data
dengan bantuan library(readxl) untuk mengambil data dengan
format .xlsx dan data tersebut dimasukkan ke dalam variabel
baru yaitu data2.
library(ggplot2)
ggplot(data2, aes(x = `Konsumsi GWh`, y = `Biaya per kWh`, color = Konsumen)) +
geom_point()+
geom_line() +
labs(
title = "Konsumsi Listrik Berdasarkan Kategori Konsumen",
x = "Nomor Urut",
y = "Konsumsi (GWh)",
color = "Kategori Konsumen"
) +
theme_minimal()
Visualisasi ini menggunakan paket
ggplot2 untuk membuat
grafik yang menggambarkan hubungan antara konsumsi listrik (dalam GWh)
dengan biaya per kWh, berdasarkan kategori konsumen. Penjelasan
Kode: - ggplot(data2, aes(...)) : Membuat plot
dari data bernama data2. Di dalam aes(), kita menentukan bahwa:
x = Konsumsi GWh → sumbu horizontal
y = Biaya per kWh → sumbu vertikal
color = Konsumen → membedakan warna berdasarkan
kategori konsumen
geom_point() : Menambahkan titik-titik data pada
plot (scatter plot), merepresentasikan masing-masing pasangan nilai x
dan y.
geom_line() : Menambahkan garis penghubung antar
titik untuk tiap kategori konsumen. Ini berguna untuk melihat pola atau
tren dalam masing-masing kelompok.
labs() : Memberikan label pada judul grafik, sumbu X
dan Y, serta legenda warna.
theme_minimal() : Menggunakan tema visual sederhana
agar tampilan plot lebih bersih dan profesional.
Interpretasi Visualisasi: - Kategori UMKM dan Rumah Tangga memiliki konsumsi listrik paling tinggi di urutan awal, namun jumlah konsumen mereka terlihat lebih sedikit karena titiknya hanya di bagian awal sumbu X.
Kategori Industri memiliki sebaran titik yang lebih panjang hingga nomor urut 400, menandakan bahwa:
Jumlah pelanggan kategori industri lebih banyak dalam data ini.
Konsumsi listrik per pelanggan di industri cenderung lebih rendah secara individu, tapi volume totalnya besar karena banyaknya pelanggan.
Kategori Pemerintah juga memiliki jumlah pelanggan terbatas (sekitar 5-6 titik), dengan konsumsi cukup tinggi, mirip dengan UMKM dan Rumah Tangga.
Pola menurun (declining pattern) tampak di semua kategori. Artinya, semakin besar nomor urut pelanggan, semakin kecil konsumsi listriknya — ini bisa mengindikasikan skala bisnis atau aktivitas dari masing-masing pelanggan makin kecil.