1. Lakukan visualisasi yang efektif untuk menjawab pertanyaan berikut tuliskan informasi tentang variabel (pengertian dari variabel tersebut, skala data variabel), sintag, output yang dihasilkan serta interpretasi.
Lakukan pengecekan apakah terdapat:
✓ Nilai yang hilang (missing values)
Tidak ada nilai yang hilang
# Baca data
data <- read.csv("heart.csv")
# Cek jumlah missing value di setiap 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
✓ Data yang tercatat ganda (duplicate records)
Terdapat 1 data duplikat, dan sudah dihapus. Dataset sekarang memiliki 302 baris. Untuk menangani data duplikat saya menggunakan langsung fitur pada excel yaitu dengan cara, Ctrl+A>Alt+A+M>Pilih nilai kolom yang duplikatnya akan di hapus>Ok. Maka data duplikat akan terhapus
# Cek dan hapus duplikat
sum(duplicated(data))
## [1] 0
df_clean <- data[!duplicated(data), ]
✓ Nilai ekstrim (outlier) pada variabel numerik
# Baca data
data <- read.csv("heart.csv")
# Fungsi deteksi outlier metode IQR
detect_outliers_iqr <- function(df) {
num_df <- df[sapply(df, is.numeric)]
outliers <- lapply(names(num_df), function(col) {
x <- num_df[[col]]
Q1 <- quantile(x, 0.25, na.rm = TRUE)
Q3 <- quantile(x, 0.75, na.rm = TRUE)
IQR <- Q3 - Q1
lower <- Q1 - 1.5 * IQR
upper <- Q3 + 1.5 * IQR
count <- sum(x < lower | x > upper, na.rm = TRUE)
data.frame(Variable = col, Total_Outliers = count,
Lower_Bound = round(lower, 2), Upper_Bound = round(upper, 2))
})
do.call(rbind, outliers)
}
# fungsi
hasil_outlier <- detect_outliers_iqr(data)
# hasil
print(hasil_outlier)
## Variable Total_Outliers Lower_Bound Upper_Bound
## 25% age 0 28.50 80.50
## 25%1 sex 0 -1.50 2.50
## 25%2 cp 0 -3.00 5.00
## 25%3 trestbps 9 90.00 170.00
## 25%4 chol 5 115.38 370.38
## 25%5 fbs 45 0.00 0.00
## 25%6 restecg 0 -1.50 2.50
## 25%7 thalach 1 84.12 215.12
## 25%8 exang 0 -1.50 2.50
## 25%9 oldpeak 5 -2.40 4.00
## 25%10 slope 0 -0.50 3.50
## 25%11 ca 24 -1.50 2.50
## 25%12 thal 2 0.50 4.50
## 25%13 target 0 -1.50 2.50
# 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
# Load libraries
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.3.2
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.3.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
# Baca data
data <- read.csv("heart.csv")
# 1. Visualisasi penyakit jantung berdasarkan jenis kelamin
data %>%
filter(target == 1) %>%
count(sex) %>%
ggplot(aes(x = factor(sex, labels = c("Perempuan", "Laki-laki")), y = n)) +
geom_bar(stat = "identity", fill = "tomato") +
geom_text(aes(label = n), vjust = -0.5) +
labs(title = "Penderita Penyakit Jantung berdasarkan Jenis Kelamin",
x = "Jenis Kelamin", y = "Jumlah")
# 2. Distribusi usia penderita penyakit jantung
data %>%
filter(target == 1) %>%
ggplot(aes(x = age)) +
geom_histogram(binwidth = 5, fill = "skyblue", color = "black") +
labs(title = "Distribusi Usia Penderita Penyakit Jantung",
x = "Usia", y = "Jumlah")
# 3. Distribusi usia dengan tekanan darah > 120 mm Hg
data %>%
filter(trestbps > 120) %>%
ggplot(aes(x = age)) +
geom_histogram(binwidth = 5, fill = "purple", color = "black") +
labs(title = "Distribusi Usia dengan Tekanan Darah > 120 mm Hg",
x = "Usia", y = "Jumlah")
Interpretasi
1. Jenis kelamin yang paling banyak mengalami penyakit jantung
Dalam data ini, laki-laki lebih banyak mengalami penyakit jantung dibandingkan perempuan. Hal ini bisa menjadi indikasi awal bahwa jenis kelamin dapat menjadi salah satu faktor risiko yang perlu diperhatikan dalam upaya pencegahan dan penanganan penyakit jantung.
2. Usia yang paling banyak mengalami penyakit jantung
Distribusi usia dari penderita penyakit jantung. Terlihat bahwa penderita paling banyak berada pada rentang usia 50–60 tahun, dengan puncak kasus sekitar 55 tahun. Setelah itu, jumlah kasus mulai menurun seiring bertambahnya usia, menunjukkan bahwa risiko tertinggi terdeteksi pada kelompok usia paruh baya hingga awal lansia.
3. Usia dengan gula darah > 120 mg/dl
Distribusi ini mengindikasikan bahwa kasus kadar gula darah tinggi lebih sering ditemukan pada kelompok usia yang lebih tua, di sini juga terlihat bahwa tekanan darah tinggi ini paling banyak ditemukan pada usia 55–65 tahun, dengan puncak jumlah kasus di sekitar usia 60 tahun. Ini menunjukkan adanya kecenderungan peningkatan tekanan darah seiring bertambahnya usia, terutama pada kelompok dewasa lanjut.
# Load libraries
library(dplyr)
library(ggplot2)
# Baca data
data <- read.csv("heart.csv")
# Tabulasi & visualisasi distribusi penyakit jantung berdasarkan kadar gula darah
data %>%
count(fbs, target) %>%
ggplot(aes(x = factor(fbs), y = n, fill = factor(target))) +
geom_bar(stat = "identity", position = position_dodge(0.9)) +
geom_text(aes(label = n), position = position_dodge(0.9), vjust = -0.5) +
labs(
title = "Distribusi Penyakit Jantung vs. Kadar Gula Darah",
x = "Kadar Gula Darah (0: ≤120 mg/dl, 1: >120 mg/dl)",
y = "Jumlah",
fill = "Penyakit Jantung"
) +
scale_fill_manual(values = c("0" = "skyblue", "1" = "yellow")) +
theme_minimal()
target= 0 (skyblue) ≤120 mg/dl
menunjukkan kelompok orang dengan kadar gula darah saat puasa normal atau rendah Jumlah penderita penyakit jantung juga cukup tinggi, tapi lebih seimbang antara yang sakit dan yang tidak. Artinya, meskipun kadar gula darah normal, risiko penyakit jantung masih ada, tapi tidak sebanyak pada kelompok gula tinggi.
target= 1(yellow) >120 mg/dl
menunjukkan kelompok orang dengan kadar gula darah saat puasa tinggi Jumlah penderita penyakit jantung lebih tinggi, menunjukkan bahwa orang dengan kadar gula darah tinggi lebih banyak yang mengalami penyakit jantung. Potensi risiko penyakit jantung bisa lebih besar pada kelompok ini.
Dapat disimpulkan bahwa, Orang yang memiliki kadar gula darah saat puasa lebih dari 120 mg/dl cenderung lebih banyak mengalami penyakit jantung dibandingkan mereka yang memiliki kadar gula darah normal atau rendah.
# Load libraries
library(dplyr)
library(ggplot2)
# Baca data
data <- read.csv("heart.csv")
# Ubah nilai 'cp' menjadi label deskriptif
data$cp <- factor(data$cp, levels = 0:3,
labels = c("Typical Angina", "Atypical Angina", "Non-anginal Pain", "Asymptomatic"))
# Hitung dan urutkan jumlah nyeri dada pada penderita penyakit jantung
cp_counts <- data %>%
filter(target == 1) %>%
count(cp) %>%
arrange(n)
# Visualisasi
ggplot(cp_counts, aes(x = reorder(cp, n), y = n, fill = cp)) +
geom_bar(stat = "identity") +
geom_text(aes(label = n), vjust = -0.5) +
labs(
title = "Jenis Nyeri Dada pada Penderita Penyakit Jantung",
x = "Jenis Nyeri Dada", y = "Jumlah Penderita", fill = NULL
) +
theme_minimal() +
scale_fill_brewer(palette = "Set2")
Interpretasi
Hasil ini menunjukkan bahwa tidak semua penderita penyakit jantung mengalami nyeri dada yang khas, seperti angina. Bahkan, lebih banyak penderita justru mengalami nyeri yang tidak khas atau bahkan tidak merasakan gejala sama sekali. Hal ini penting untuk diperhatikan dalam diagnosis dan penanganan, karena penderita dengan nyeri dada yang tidak khas atau tanpa gejala bisa saja luput dari pemeriksaan dini. Oleh karena itu, edukasi dan pemeriksaan rutin tetap penting, meskipun seseorang tidak merasakan nyeri dada yang spesifik.
library(ggplot2)
library(dplyr)
# Baca data dan konversi kolom kategori ke faktor
heart <- read.csv("heart.csv") %>%
mutate(across(c(cp, ca, thal, target), as.factor))
# Fungsi untuk membuat plot proporsi per kategori
plot_proporsi <- function(var) {
heart %>%
count(!!sym(var), target) %>%
group_by(!!sym(var)) %>%
mutate(proporsi = n / sum(n)) %>%
ggplot(aes_string(x = var, y = "proporsi", fill = "target")) +
geom_bar(stat = "identity") +
geom_text(aes(label = scales::percent(proporsi, 1)),
position = position_stack(vjust = 0.5), color = "white") +
scale_y_continuous(labels = scales::percent) +
labs(
title = paste("Proporsi Penyakit Jantung berdasarkan", var),
x = var, y = "Proporsi", fill = "Target"
) +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5))
}
# Tampilkan hasil plot
plot_proporsi("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.
plot_proporsi("ca")
plot_proporsi("thal")
Interpretasi
Proporsi Penyakit Jantung berdasarkan cp
Jenis nyeri dada sangat berkaitan dengan keberadaan penyakit jantung. Semakin tinggi nilai cp (terutama cp=1), semakin besar kemungkinan seseorang mengidap penyakit jantung.
Proporsi Penyakit Jantung berdasarkan ca
Semakin banyak pembuluh darah yang tampak normal (ca 1-3), kemungkinan seseorang tidak menderita penyakit jantung cenderung meningkat. Namun, pada kategori ca = 4 terjadi anomali, di mana proporsi penderita penyakit jantung kembali tinggi.
penyakit jantung berdasarkan variabel thal
Visualisasi ini menggambarkan bahwa nilai thal tertentu (seperti thal = 2) memiliki kecenderungan lebih tinggi terhadap risiko penyakit jantung dibandingkan nilai lainnya.
library(ggplot2)
library(dplyr)
# Baca data
heart <- read.csv("heart.csv")
# Konversi target ke faktor
heart$target <- factor(heart$target, labels = c("Tidak", "Ya"))
# Visualisasi scatter plot + garis tren
ggplot(heart, aes(x = age, y = thalach, color = target)) +
geom_point(alpha = 0.6) +
geom_smooth(method = "loess", se = FALSE, linetype = "solid", size = 1.2) +
labs(
title = "Hubungan antara Usia dan Detak Jantung Maksimum (thalach)",
subtitle = "Dibedakan berdasarkan status Penyakit Jantung",
x = "Usia",
y = "Detak Jantung Maksimum (thalach)",
color = "Penyakit Jantung"
) +
theme_minimal(base_size = 12)
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## `geom_smooth()` using formula = 'y ~ x'
Interpretasi
Semakin bertambah usia, detak jantung maksimum cenderung menurun. Namun, penurunan ini tidak konstan atau proporsional di setiap usia, melainkan mengalami perubahan kemiringan atau bahkan sedikit naik-turun di titik-titik tertentu, karakteristik ini menunjukkan hubungan non-linear. Cara mengetahuinya jika garisnya lurus, maka hubungannya linear maka, jika garisnya melengkung, naik-turun, atau membentuk pola lain, maka hubungannya non-linear. Bentuk garis menunjukkan adanya kurva, yang mengindikasikan relasi non-linear antara usia dan detak jantung maksimum.
library(ggplot2)
library(reshape2)
## Warning: package 'reshape2' was built under R version 4.3.3
# Baca dan proses data
cor_matrix <- cor(read.csv("heart.csv")[, sapply(read.csv("heart.csv"), is.numeric)], use = "complete.obs")
melted_cor <- melt(round(cor_matrix, 2))
# Plot heatmap
ggplot(melted_cor, aes(Var1, Var2, fill = value)) +
geom_tile(color = "white") +
scale_fill_gradient2(low = "blue", mid = "white", high = "red",
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 = NULL, y = NULL) +
coord_fixed()
Interpretasi
Warna merah menunjukkan korelasi positif yang kuat, artinya jika satu variabel naik, variabel lainnya cenderung ikut naik. Sebaliknya, warna biru menunjukkan korelasi negatif, yaitu jika satu variabel naik, variabel lainnya cenderung turun. Warna yang semakin mendekati putih berarti korelasi mendekati nol, atau tidak ada hubungan linear yang kuat antara dua variabel. Misalnya, variabel age memiliki korelasi positif dengan trestbps (tekanan darah istirahat) dan chol (kolesterol), yang artinya semakin tua seseorang, cenderung tekanan darah dan kolesterolnya juga meningkat. Sementara itu, thalach (detak jantung maksimal) menunjukkan korelasi negatif terhadap age dan exang (angina akibat latihan), yang dapat diartikan bahwa orang yang lebih tua atau mengalami angina saat latihan cenderung memiliki detak jantung maksimal yang lebih rendah.
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.
summary hasil analisis
Jenis Nyeri Dada (cp) merupakan variabel yang paling berkorelasi positif dengan penyakit jantung. Artinya, tipe nyeri dada tertentu sering muncul pada penderita penyakit jantung.
Detak Jantung Maksimum (thalach) juga memiliki korelasi positif terhadap penyakit jantung. Detak jantung yang tinggi saat latihan bisa menjadi indikasi adanya gangguan jantung.
Oldpeak (depresi ST) memiliki korelasi negatif, menunjukkan bahwa nilai oldpeak yang tinggi cenderung dimiliki oleh pasien yang tidak menderita penyakit jantung.
Angina karena latihan (exang) juga berkorelasi negatif, menunjukkan bahwa pasien yang mengalami angina saat olahraga cenderung memiliki risiko lebih rendah (atau lebih tinggi tergantung interpretasi target).
Jenis Kelamin: Lebih banyak penderita penyakit jantung adalah laki-laki dibanding perempuan.
Kadar gula darah puasa (fbs) dan kolesterol (chol) memiliki korelasi sangat rendah terhadap penyakit jantung, yang berarti tidak terlalu memengaruhi secara langsung dalam dataset ini.
Hal-Hal yang Dapat Mencegah Penyakit Jantung
Olahraga Teratur – Membantu menjaga tekanan darah, meningkatkan detak jantung sehat, dan mengurangi stres.
Pola Makan Sehat – Menghindari makanan tinggi kolesterol, lemak jenuh, dan gula berlebih dapat menjaga kesehatan jantung.
Menghindari Merokok dan Alkohol – Zat-zat ini memperburuk kondisi pembuluh darah dan meningkatkan risiko jantung.
Menjaga Berat Badan Ideal – Obesitas meningkatkan tekanan darah dan risiko diabetes, yang menjadi faktor risiko jantung.
Rutin Pemeriksaan Kesehatan – Mengetahui lebih awal gejala seperti nyeri dada, detak jantung tidak normal, atau tekanan darah tinggi bisa menyelamatkan nyawa.
Indikasi Potensial Penyakit Jantung
Tipe Nyeri Dada (cp) → Terutama tipe 1 dan 2 dalam data, sering diasosiasikan dengan penyakit jantung.
Detak Jantung Maksimum (thalach) → Jika sangat tinggi atau sangat rendah saat olahraga bisa menjadi tanda peringatan.
Oldpeak (Depresi ST) → Nilai tinggi bisa mengindikasikan masalah iskemik.
Angina Saat Latihan (exang) → Gejala ini sering muncul pada penderita jantung koroner.
Kondisi Elektrokardiografi (restecg) dan kemiringan segmen ST (slope) → Bisa menunjukkan abnormalitas pada aktivitas listrik jantung.
Kesimpulan analisis ini menunjukkan bahwa kombinasi antara gejala fisik (seperti nyeri dada dan detak jantung), hasil tes medis (seperti EKG dan ST segment), serta gaya hidup sangat mempengaruhi risiko penyakit jantung. Pencegahan bisa dilakukan dengan gaya hidup sehat, deteksi dini, dan kesadaran terhadap gejala-gejala awal. Pemeriksaan rutin dan edukasi kesehatan juga sangat penting untuk mengurangi angka kejadian penyakit jantung.
# Load library
library(ggplot2)
library(readr)
## Warning: package 'readr' was built under R version 4.3.3
library(dplyr)
# Membuat data (bisa disesuaikan jika dari CSV)
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))
)
# Visualisasi
ggplot(data, aes(x = Konsumsi_GWh, y = Biaya_per_kWh, color = Konsumen)) +
geom_point(size = 1.5) + # Titik-titik data
geom_smooth(method = "lm", se = FALSE) + # Garis tren linear per kelompok
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'
Bagian ggplot2 digunakan untuk membuat visualisasi data,
readr untuk membaca file CSV jika diperlukan, dan
dplyr untuk manipulasi data. Selanjutnya, bagian
data <- data.frame(...) digunakan untuk membuat data
secara manual ke dalam sebuah data frame. Nilai-nilai diisi langsung
dalam bentuk vektor dan dikombinasikan menjadi satu data frame. Bagian
visualisasi dimulai dengan fungsi ggplot(...), yang
merupakan inti dari paket ggplot2. Dalam fungsi ini, kita
mendefinisikan sumbu-x (x = Konsumsi_GWh), sumbu-y
(y = Biaya_per_kWh), dan warna garis atau titik berdasarkan
jenis konsumen (color = Konsumen). Kemudian,
geom_point(size = 1.5) menambahkan titik-titik data ke
grafik, dengan ukuran titik diatur agar terlihat jelas. Ini menampilkan
setiap pengamatan sebagai titik. Lalu,
geom_smooth(method = "lm", se = FALSE) digunakan untuk
menambahkan garis tren linear (regresi linier) untuk setiap kelompok
konsumen. method = "lm" menyatakan bahwa metode regresi
linier digunakan, dan se = FALSE artinya tidak ditampilkan
area bayangan standar error di sekitar garis. Bagian
labs(...) digunakan untuk menambahkan judul dan label pada
sumbu-sumbu grafiK. Terakhir, theme_minimal() memberikan
tampilan visual yang bersih dan sederhana tanpa garis latar atau
dekorasi berlebihan, agar grafik lebih fokus pada data dan tren yang
ditampilkan.
Interpretasi
visualisasi tersebut memperlihatkan bahwa semakin tinggi konsumsi listrik, maka biaya per kWh cenderung menurun, atau dengan kata lain terdapat skema tarif bertingkat di mana konsumen besar mendapat tarif yang lebih murah. Seperti, Industri (merah) memiliki konsumsi listrik paling tinggi (hingga lebih dari 300 GWh) dan biaya listrik per kWh yang paling rendah (sekitar 1.200 Rp), menandakan mereka mendapat tarif istimewa karena konsumsi besar. Kantor Pemerintah (hijau) menunjukkan tren menurun juga, namun dengan konsumsi lebih rendah dari industri dan biaya per kWh yang lebih tinggi dibanding industri. Rumah Tangga (biru) memiliki biaya listrik per kWh yang lebih tinggi dari industri dan pemerintah, walaupun tetap menunjukkan penurunan biaya saat konsumsi meningkat. UMKM (ungu) terlihat sebagai kelompok dengan tarif listrik per kWh paling tinggi (mendekati 1.700 Rp) dan konsumsi listrik yang relatif rendah, artinya kelompok ini mungkin belum menikmati efisiensi tarif seperti sektor lain.