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.

library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.3.3
## Warning: package 'ggplot2' was built under R version 4.3.3
## Warning: package 'tibble' was built under R version 4.3.3
## Warning: package 'tidyr' was built under R version 4.3.3
## Warning: package 'readr' was built under R version 4.3.3
## Warning: package 'purrr' was built under R version 4.3.3
## Warning: package 'dplyr' was built under R version 4.3.3
## Warning: package 'stringr' was built under R version 4.3.3
## Warning: package 'forcats' was built under R version 4.3.3
## Warning: package 'lubridate' was built under R version 4.3.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(summarytools)
## Warning: package 'summarytools' was built under R version 4.3.3
## 
## Attaching package: 'summarytools'
## 
## The following object is masked from 'package:tibble':
## 
##     view
library(ggplot2)
library(dplyr)
library(ggcorrplot)
## Warning: package 'ggcorrplot' was built under R version 4.3.3
# Baca dataset
data <- read.csv("C:/Users/ASUS/Documents/SEMESTER 4/PSD/heart.csv")

a. Lakukan pengecekan

# 1. Pengecekan Missing Values
# Cek missing values
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

Penanganan:
Jika terdapat nilai yang hilang, bisa dihapus atau diisi. Dalam kasus ini, kita hapus jika hanya sedikit.

# Hapus baris dengan NA
data <- na.omit(data)
# 2. Pengecekan Duplikat
# Jumlah data duplikat
sum(duplicated(data))
## [1] 1
# Hapus duplikat
data <- data[!duplicated(data), ]

Penanganan:
Duplikat dihapus karena berpotensi mendistorsi analisis.

# 3. Pengecekan Outlier
# Ambil variabel numerik
numeric_data <- select_if(data, is.numeric)

# Boxplot semua variabel numerik
boxplot(numeric_data, main = "Boxplot Variabel Numerik", las = 2)

Penanganan Outlier:
Outlier akan dihapus menggunakan metode IQR.

remove_outliers <- function(x) {
  Q1 <- quantile(x, 0.25, na.rm = TRUE)
  Q3 <- quantile(x, 0.75, na.rm = TRUE)
  IQR <- Q3 - Q1
  x[x < (Q1 - 1.5 * IQR) | x > (Q3 + 1.5 * IQR)] <- NA
  return(x)
}

# Terapkan fungsi ke semua variabel numerik
clean_data <- numeric_data %>% mutate_all(remove_outliers)

# Hapus NA akibat outlier
clean_data <- na.omit(clean_data)
# 4. Statistik Deskriptif
# Statistik deskriptif setelah pembersihan
dfSummary(clean_data)
## Data Frame Summary  
## clean_data  
## Dimensions: 228 x 14  
## Duplicates: 0  
## 
## -------------------------------------------------------------------------------------------------------------
## No   Variable    Stats / Values             Freqs (% of Valid)    Graph                  Valid      Missing  
## ---- ----------- -------------------------- --------------------- ---------------------- ---------- ---------
## 1    age         Mean (sd) : 53.3 (9.2)     40 distinct values              :            228        0        
##      [integer]   min < med < max:                                     . . . : : .        (100.0%)   (0.0%)   
##                  29 < 54 < 76                                         : : : : : :                            
##                  IQR (CV) : 15 (0.2)                                  : : : : : : .                          
##                                                                     : : : : : : : :                          
## 
## 2    sex         Min  : 0                   0 :  74 (32.5%)       IIIIII                 228        0        
##      [integer]   Mean : 0.7                 1 : 154 (67.5%)       IIIIIIIIIIIII          (100.0%)   (0.0%)   
##                  Max  : 1                                                                                    
## 
## 3    cp          Mean (sd) : 0.9 (1)        0 : 108 (47.4%)       IIIIIIIII              228        0        
##      [integer]   min < med < max:           1 :  42 (18.4%)       III                    (100.0%)   (0.0%)   
##                  0 < 1 < 3                  2 :  61 (26.8%)       IIIII                                      
##                  IQR (CV) : 2 (1.1)         3 :  17 ( 7.5%)       I                                          
## 
## 4    trestbps    Mean (sd) : 128.7 (15.3)   38 distinct values        . : .              228        0        
##      [integer]   min < med < max:                                     : : :              (100.0%)   (0.0%)   
##                  94 < 130 < 170                                     : : : :                                  
##                  IQR (CV) : 20 (0.1)                                : : : : : .                              
##                                                                   . : : : : : : .                            
## 
## 5    chol        Mean (sd) : 242.4 (44.3)   132 distinct values         . :              228        0        
##      [integer]   min < med < max:                                       : : :            (100.0%)   (0.0%)   
##                  131 < 239 < 360                                      . : : : :                              
##                  IQR (CV) : 59.5 (0.2)                                : : : : : :                            
##                                                                   . : : : : : : : : .                        
## 
## 6    fbs         1 distinct value           0 : 228 (100.0%)      IIIIIIIIIIIIIIIIIIII   228        0        
##      [integer]                                                                           (100.0%)   (0.0%)   
## 
## 7    restecg     Mean (sd) : 0.5 (0.5)      0 : 105 (46.1%)       IIIIIIIII              228        0        
##      [integer]   min < med < max:           1 : 121 (53.1%)       IIIIIIIIII             (100.0%)   (0.0%)   
##                  0 < 1 < 2                  2 :   2 ( 0.9%)                                                  
##                  IQR (CV) : 1 (0.9)                                                                          
## 
## 8    thalach     Mean (sd) : 151.1 (22.5)   81 distinct values                : :        228        0        
##      [integer]   min < med < max:                                           . : :        (100.0%)   (0.0%)   
##                  88 < 155 < 202                                         : : : : :                            
##                  IQR (CV) : 30.8 (0.1)                                : : : : : : .                          
##                                                                   . . : : : : : : :                          
## 
## 9    exang       Min  : 0                   0 : 156 (68.4%)       IIIIIIIIIIIII          228        0        
##      [integer]   Mean : 0.3                 1 :  72 (31.6%)       IIIIII                 (100.0%)   (0.0%)   
##                  Max  : 1                                                                                    
## 
## 10   oldpeak     Mean (sd) : 0.9 (1)        35 distinct values    :                      228        0        
##      [numeric]   min < med < max:                                 :                      (100.0%)   (0.0%)   
##                  0 < 0.6 < 4                                      :                                          
##                  IQR (CV) : 1.6 (1.1)                             : . .                                      
##                                                                   : : : : . :   .                            
## 
## 11   slope       Mean (sd) : 1.5 (0.6)      0 :  11 ( 4.8%)                              228        0        
##      [integer]   min < med < max:           1 : 103 (45.2%)       IIIIIIIII              (100.0%)   (0.0%)   
##                  0 < 1.5 < 2                2 : 114 (50.0%)       IIIIIIIIII                                 
##                  IQR (CV) : 1 (0.4)                                                                          
## 
## 12   ca          Mean (sd) : 0.5 (0.7)      0 : 146 (64.0%)       IIIIIIIIIIII           228        0        
##      [integer]   min < med < max:           1 :  55 (24.1%)       IIII                   (100.0%)   (0.0%)   
##                  0 < 0 < 2                  2 :  27 (11.8%)       II                                         
##                  IQR (CV) : 1 (1.5)                                                                          
## 
## 13   thal        Mean (sd) : 2.3 (0.6)      1 :  11 ( 4.8%)                              228        0        
##      [integer]   min < med < max:           2 : 134 (58.8%)       IIIIIIIIIII            (100.0%)   (0.0%)   
##                  1 < 2 < 3                  3 :  83 (36.4%)       IIIIIII                                    
##                  IQR (CV) : 1 (0.2)                                                                          
## 
## 14   target      Min  : 0                   0 :  96 (42.1%)       IIIIIIII               228        0        
##      [integer]   Mean : 0.6                 1 : 132 (57.9%)       IIIIIIIIIII            (100.0%)   (0.0%)   
##                  Max  : 1                                                                                    
## -------------------------------------------------------------------------------------------------------------

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.

#Visualisasi Penyakit Jantung dengan Jenis kelamin 
ggplot(data, aes(factor(sex), fill = factor(target)))+
  geom_bar(position = "dodge")+
  labs(title = "Distribusi Heart Disease berdasarkan Jenis Kelamin", 
       x = "Jenis Kelamin (0 = Perempuan, 1 = Laki-laki)",
       y = "Jumlah",
       fill = "Heart Disease") + 
  theme_minimal()

Grafik menunjukkan distribusi penyakit jantung berdasarkan jenis kelamin. terlihat bahwa pada kelompok perempuan (0), pada jumlah yang meanderita penyakit jantung (kode 1) lebih tinggi dibandingkan yang tidak menderita (kode 0). Sementara pada kelompok laki-laki (1), jumlah yang tidak menderita penyakit jantung jumlah yang tidak menderita penyakit jantung lebih tinggi dibandingkan perempuan, namun jumlah yang menderita juga cukup tinggi. Secara keseluruhan, laki-laki memiliki jumlah penyakit jantung yang lebih banyak dibanding perempuan.

#Visualisasi usia yang mengalami heart disease
data_hd <- filter(data, target == 1)
ggplot(data_hd, aes(x = age)) +
  geom_histogram(bins = 15, fill = "blue", color = "black") +
  labs(title = "Distribusi usia yang mengalami Heart Disease",
       x = "Usia",
       y = "Jumlah") +
  theme_minimal()

Grafik menunjukkan distribusi usia penderita penyakit jantung. Terlihat bahwa penderita paling banyak berada pada rentang usia sekitar 50-60 tahun. JUmlah kasus mulai meningkat sejak usia 40-an tahun dan menurun setelah usia 65 tahun. Hal ini menunjukkan bahwa resiko penyakit jantung lebih tinggi pada usia paruh baya hingga awal lansia.

# Visualisasi usia dengan gula darah tinggi
data_gula <- filter(data, fbs == 1)
ggplot(data_gula, aes(x = age)) +
  geom_histogram(bins = 15, fill = "skyblue", color = "black") +
  labs(title = "Distribusi Usia dengan Gula Darah > 120 mg/dl",
       x = "Usia",
       y = "Jumlah") +
  theme_minimal()

Grafik menunjukkan distribusi usia individu dengan kadar gula darah lebih dari 120 mg/dl. Terlihat bahwa kelompok usia sekitar 55 hingga 60 tahun memiliki jumlah terbanyak dengan kadar gula darah tinggi. Secara umum, kasus kadar gula darah tinggi lebih banyak ditemukan pada usia paruh baya hingga menjelang lansia.

c. Lakukan analisis untuk mengetahui, apakah kadar gula darah seseorang yang lebih besar dari 120 paling banyak mengalami Heart desease?

# Buat tabulasi silang
table_fbs <- table(data$fbs, data$target)
table_fbs
##    
##       0   1
##   0 116 141
##   1  22  23
# Hitung proporsi
prop.table(table_fbs, margin = 1) * 100
##    
##            0        1
##   0 45.13619 54.86381
##   1 48.88889 51.11111

Orang dengan kadar gula darah > 120 (fbs = 1) tidak secara signifikan lebih banyak mengalami penyakit jantung, karena proporsinya (51.11%) lebih rendah sedikit dibanding yang fbs = 0 (54.86%).Jadi, kadar gula darah > 120 bukan faktor dominan dalam penyakit jantung.

d. Lakukan identifikasi untuk mengetahui jenis nyeri dada yang paling banyak terjadi pada seseorang mengalami Heart desease

# Hitung frekuensi jenis nyeri dada pada pasien dengan penyakit jantung (target = 1)
nyeri_terbanyak <- data %>%
  filter(target == 1) %>%
  count(cp, sort = TRUE)

nyeri_terbanyak
##   cp  n
## 1  2 68
## 2  1 41
## 3  0 39
## 4  3 16
# Visualisasikan jumlah jenis nyeri dada
ggplot(nyeri_terbanyak, aes(x = factor(cp), y = n, fill = factor(cp))) +
  geom_bar(stat = "identity") +
  labs(
    title = "Distribusi Jenis Nyeri Dada pada Pasien Penyakit Jantung",
    x = "Jenis Nyeri Dada (cp)",
    y = "Jumlah Pasien",
    fill = "Kode CP"
  ) +
  theme_minimal(base_size = 14)

Grafik menunjukkan distribusi jenis nyeri dada (kode CP) pada pasien penyakit jantung. Jenis nyeri dada dengan kode 2 merupakan yang paling banyak dialami pasien, diikuti oleh kode 1 dan 0 dengan jumlah yang hampir sama. Jenis nyeri dada dengan kode 3 memiliki jumlah pasien paling sedikit. Ini menunjukkan bahwa jenis nyeri dada tertentu khususnya kode 2 lebih umum dikaitkan dengan penyakit jantung.

e. Buat visualisasi Bar plot proporsi heart desease terhadap variabel kategorikal cp, ca, dan thal. Interpretasikan

# Fungsi bantu untuk membuat bar plot proporsi
plot_prop <- function(var_name) {
  data %>%
    group_by(.data[[var_name]], target) %>%
    summarise(n = n(), .groups = 'drop') %>%
    group_by(.data[[var_name]]) %>%
    mutate(prop = n / sum(n)) %>%
    ggplot(aes(x = factor(.data[[var_name]]), y = prop, fill = factor(target))) +
    geom_bar(stat = "identity", position = "dodge") +
    labs(title = paste("Proporsi Heart Disease berdasarkan", var_name),
         x = var_name,
         y = "Proporsi",
         fill = "Heart Disease (1 = Ya)") +
    theme_minimal()
}
plot_prop("cp")

Grafik menunjukkan proporsi penyakit jantung berdasarkan nilai cp. Bar berwarna orange mewakili proporsi individu tanpa penyakit jantung (0), dan bar berwarna biru muda mewakili individu dengan penyakit jantung (1). Dari grafik, terlihat bahwa pada kategori cp = 0 (tanpa nyeri dada atau nyeri dada atipikal), proporsi individu yang mengalami penyakit jantung lebih rendah dibandingkan dengan kategori cp = 2 atau cp = 3, di mana proporsi individu dengan penyakit jantung lebih tinggi.

plot_prop("ca")

Grafik menunjukkan proporsi penyakit jantung berdasarkan nilai ca. Bar berwarna orange mewakili individu tanpa penyakit jantung (0), sedangkan bar biru muda mewakili individu dengan penyakit jantung (1). Terlihat bahwa semakin tinggi nilai ca, proporsi individu tanpa penyakit jantung cenderung meningkat, sedangkan proporsi penyakit jantung lebih banyak ditemukan pada ca bernilai 0 atau 4.

plot_prop("thal")

Grafik menunjukkan proporsi individu dengan dan tanpa penyakit jantung berdasarkan nilai thal. Warna orange mewakili individu tanpa penyakit jantung, sedangkan warna biru muda mewakili individu yang mengidap penyakit jantung. Terlihat bahwa pada nilai thal = 2, proporsi individu dengan penyakit jantung cukup dominan, menunjukkan hubungan yang kuat antara nilai ini dan kemungkinan menderita penyakit jantung. Sebaliknya, pada nilai thal = 3, mayoritas individu justru tidak menderita penyakit jantung. Sementara itu, pada nilai thal = 1, proporsi individu tanpa penyakit jantung juga lebih tinggi dibandingkan yang menderita dan pada thal= 0, proporsi individu dengan dan tanpa penyakit jantung sama.

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 dengan garis regresi linear
ggplot(data, aes(x = age, y = thalach, color = factor(target))) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "lm", se = FALSE) +
  labs(title = "Hubungan antara Age dan Thalach",
       subtitle = "Dibedakan berdasarkan status Heart Disease",
       x = "Usia",
       y = "Detak Jantung Maksimum (thalach)",
       color = "Heart Disease") +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

Grafik menunjukkan hubungan antara usia dan detak jantung maksimum (thalach) yang dibedakan berdasarkan status penyakit jantung. Terlihat bahwa secara umum, detak jantung maksimum cenderung menurun seiring bertambahnya usia. Penderita penyakit jantung warna biru cenderung memiliki detak jantung maksimum yang lebih tinggi dibandingkan yang tidak menderita warna merah, terutama pada usia lebih muda.

g. Buat heatmap korelasi antar variabel yang berskala interval atau rasio kemudian interpretasukan hasil yang didapat

# Ambil variabel numerik
numeric_data <- select(data, where(is.numeric))

# Hitung korelasi Pearson
cor_matrix <- cor(numeric_data)

# Visualisasi heatmap korelasi
ggcorrplot(cor_matrix, 
           method = "circle", 
           type = "lower", 
           lab = TRUE,
           colors = c("red", "white", "blue"),
           title = "Heatmap Korelasi Antar Variabel Numerik")

Berdasarkan heatmap korelasi antar variabel numerik, terlihat bahwa beberapa variabel memiliki hubungan yang cukup kuat terhadap variabel target (penyakit jantung). Variabel cp (jenis nyeri dada) menunjukkan korelasi positif dengan target, yang berarti semakin tinggi nilai cp, semakin besar kemungkinan seseorang menderita penyakit jantung. Selain itu, thalach (detak jantung maksimum) juga berkorelasi positif, menunjukkan bahwa individu dengan detak jantung maksimum yang lebih tinggi cenderung memiliki risiko lebih besar. Sebaliknya, variabel oldpeak (depresi ST setelah olahraga) dan exang (angina akibat olahraga) menunjukkan korelasi negatif dengan target, artinya semakin tinggi nilainya, semakin kecil kemungkinan individu tersebut mengidap penyakit jantung. Sementara itu, variabel lain seperti chol, fbs, dan restecg memiliki korelasi yang sangat lemah terhadap target, menunjukkan bahwa pengaruhnya terhadap risiko penyakit jantung relatif kecil.

h.

SUMMARY HASIL Dari hasil eksplorasi data heat disease, ditemukan beberapa pola penting mengenai faktor dan indikasi penyakit jantung

Jumlah pembulu besar yang terdeteksi oleh fluoroskopi (ca) juga menjadi indikator kuat.

Pencegahan Penyakit Jantung - Menjaga tekanan darah dan gula darah tetap normal, karena tekanan darah tinggi dan kadar gula darah tinggi berkorelasi dengan resiko jantung.

##2. Dari data berikut, Buat diagram yang sama dengan contoh. Serta jelaskan maksud setiap dari bagian sintag tersebut. Kemudian interpretasikan.

#Membuat data frame
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 Pemerintahan", 5),
                rep("UMKM", 7))
)
ggplot(data, aes(x = Konsumsi_GWh, y = Biaya_per_kWh, color = Konsumen)) +
  geom_point(size = 2) +
  geom_smooth(method = "lm", se = FALSE) +
  labs(title = "Biaya Listrik per kWh Menurun Seiring Kenaikan Konsumsi",
       x = "Total Konsumsi Listrik (GWh)",
       y = "Biaya per kWh (Rupiah)",
       caption = "Data simulasi untuk keperluan edukasi") +
  coord_cartesian(xlim = c(0, 420)) + 
  theme_minimal(base_size = 16)
## `geom_smooth()` using formula = 'y ~ x'

Interpretasi

Grafik menunjukkan bahwa biaya listrik per kWh cenderung menurun seiring dengan meningkatnya total konsumsi listrik. Pola ini terlihat pada seluruh kategori konsumen, penurunan paling signifikan berada pada sektor industri. Hal ini menunjukkan bahwa semakin besar konsumsi listrik, semakin rendah tarif per kWh yang dikenakan, mencerminkan andanya efesiensi atau skema tarif berjenjang. Sebaliknya, UMKM dan rumah tangga memiliki konsumsi lebih rendah tetap dikenakan tarif per kWh yang relatif tinggi.