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.

  1. 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
  1. 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.
# 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.

  1. Lakukan analisis untuk mengetahui, apakah kadar gula darah seseorang yang lebih besar dari 120 paling banyak mengalami Heart desease?
# 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.

  1. Lakukan identifikasi untuk mengetahui jenis nyeri dada yang paling banyak terjadi pada seseorang mengalami Heart desease
# 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.

  1. Buat visualisasi Bar plot proporsi heart desease terhadap variabel kategorikal cp, ca, dan thal. Interpretasikan.
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.

  1. 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?
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.

  1. Buat heatmap korelasi antar variabel yang berskala interval atau rasio kemudian interpretasukan hasil yang didapat
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.

  1. 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

  1. Olahraga Teratur – Membantu menjaga tekanan darah, meningkatkan detak jantung sehat, dan mengurangi stres.

  2. Pola Makan Sehat – Menghindari makanan tinggi kolesterol, lemak jenuh, dan gula berlebih dapat menjaga kesehatan jantung.

  3. Menghindari Merokok dan Alkohol – Zat-zat ini memperburuk kondisi pembuluh darah dan meningkatkan risiko jantung.

  4. Menjaga Berat Badan Ideal – Obesitas meningkatkan tekanan darah dan risiko diabetes, yang menjadi faktor risiko jantung.

  5. 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

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.

  1. Dari data berikut, Buat diagram yang sama dengan contoh. Serta jelaskan maksud setiap dari bagian sintag tersebut. Kemudian interpretasikan.
# 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.