Variabel

library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.3.3
data <- read.csv("D:/Kuliah Semester 4/PSD/heart.csv")
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 ...
ggplot(data, aes(x = factor(target), y = chol, fill = factor(target))) +
  geom_boxplot() +
  labs(x = "Status Penyakit Jantung (0 = Tidak, 1 = Ya)",
       y = "Kadar Kolesterol (mg/dl)",
       title = "Distribusi Kolesterol berdasarkan Status Penyakit Jantung") +
  theme_minimal()

Interpretasi: Median kadar kolestrol pada penderita penyakit jantung sedikit lebih rendah dibanding yang tidak sakit. Kedua kelompok punya sebaran data yang mirip dan sama-sama memiliki outliner(kolesterol tinggi). Tidak ada perbedaan mencolok, jadi kolesterol bukan satu-satunya indikator kuat penyakit jantung dalam data ini.

    • Nilai yang hilang (missing values)
data <- read.csv("D:/Kuliah Semester 4/PSD/heart.csv")
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 <- read.csv("D:/Kuliah Semester 4/PSD/heart.csv")
sum(duplicated(data))
## [1] 1
#menghapus agar analisis tidak bias
data <- data[!duplicated(data), ]
data <- read.csv("D:/Kuliah Semester 4/PSD/heart.csv")
num_vars <- sapply(data, is.numeric)
numeric_data <- data[, num_vars]

# Boxplot untuk melihat outlier
boxplot(numeric_data, main = "Boxplot Variabel Numerik", las = 2)

# Contoh menangani outlier dengan winsorizing (memotong ujung distribusi)
data <- read.csv("D:/Kuliah Semester 4/PSD/heart.csv")

# Fungsi untuk menghapus outlier berdasarkan IQR
remove_outliers <- function(data, variable) {
  Q1 <- quantile(data[[variable]], 0.25)
  Q3 <- quantile(data[[variable]], 0.75)
  IQR_value <- Q3 - Q1
  
  lower_bound <- Q1 - 1.5 * IQR_value
  upper_bound <- Q3 + 1.5 * IQR_value
  
  cleaned_data <- data[data[[variable]] >= lower_bound & data[[variable]] <= upper_bound, ]
  return(cleaned_data)
}

# Menghapus outlier pada kolom chol
data_clean <- remove_outliers(data, "chol")

# Menghapus outlier pada kolom trestbps dari data yang sudah dibersihkan chol-nya
data_clean <- remove_outliers(data_clean, "trestbps")

# Melihat dimensi data sebelum dan sesudah
cat("Sebelum: ", nrow(data), "baris\n")
## Sebelum:  303 baris
cat("Sesudah: ", nrow(data_clean), "baris\n")
## Sesudah:  289 baris
# Deskriptif statistik
summary(numeric_data)
##       age             sex               cp           trestbps    
##  Min.   :29.00   Min.   :0.0000   Min.   :0.000   Min.   : 94.0  
##  1st Qu.:47.50   1st Qu.:0.0000   1st Qu.:0.000   1st Qu.:120.0  
##  Median :55.00   Median :1.0000   Median :1.000   Median :130.0  
##  Mean   :54.37   Mean   :0.6832   Mean   :0.967   Mean   :131.6  
##  3rd Qu.:61.00   3rd Qu.:1.0000   3rd Qu.:2.000   3rd Qu.:140.0  
##  Max.   :77.00   Max.   :1.0000   Max.   :3.000   Max.   :200.0  
##       chol            fbs            restecg          thalach     
##  Min.   :126.0   Min.   :0.0000   Min.   :0.0000   Min.   : 71.0  
##  1st Qu.:211.0   1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.:133.5  
##  Median :240.0   Median :0.0000   Median :1.0000   Median :153.0  
##  Mean   :246.3   Mean   :0.1485   Mean   :0.5281   Mean   :149.6  
##  3rd Qu.:274.5   3rd Qu.:0.0000   3rd Qu.:1.0000   3rd Qu.:166.0  
##  Max.   :564.0   Max.   :1.0000   Max.   :2.0000   Max.   :202.0  
##      exang           oldpeak         slope             ca        
##  Min.   :0.0000   Min.   :0.00   Min.   :0.000   Min.   :0.0000  
##  1st Qu.:0.0000   1st Qu.:0.00   1st Qu.:1.000   1st Qu.:0.0000  
##  Median :0.0000   Median :0.80   Median :1.000   Median :0.0000  
##  Mean   :0.3267   Mean   :1.04   Mean   :1.399   Mean   :0.7294  
##  3rd Qu.:1.0000   3rd Qu.:1.60   3rd Qu.:2.000   3rd Qu.:1.0000  
##  Max.   :1.0000   Max.   :6.20   Max.   :2.000   Max.   :4.0000  
##       thal           target      
##  Min.   :0.000   Min.   :0.0000  
##  1st Qu.:2.000   1st Qu.:0.0000  
##  Median :2.000   Median :1.0000  
##  Mean   :2.314   Mean   :0.5446  
##  3rd Qu.:3.000   3rd Qu.:1.0000  
##  Max.   :3.000   Max.   :1.0000
    • Jenis Kelamin yang paling banyak mengalami Heart desease
library(ggplot2)
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
data$sex <- factor(data$sex, labels = c("Perempuan", "Laki-laki"))

ggplot(data %>% filter(target == 1), aes(x = sex)) +
  geom_bar(fill = "tomato") +
  labs(title = "Jumlah Penderita Penyakit Jantung Berdasarkan Jenis Kelamin",
       x = "Jenis Kelamin",
       y = "Jumlah Kasus")

ggplot(data %>% filter(target == 1), aes(x = age)) +
  geom_histogram(binwidth = 2, fill = "steelblue", color = "black") +
  labs(title = "Distribusi Usia Penderita Penyakit Jantung",
       x = "Usia",
       y = "Jumlah")

ggplot(data %>% filter(fbs == 1), aes(x = age)) +
  geom_histogram(binwidth = 2, fill = "darkgreen", color = "black") +
  labs(title = "Distribusi Usia dengan Gula Darah > 120 mg/dl",
       x = "Usia",
       y = "Jumlah")

  1. Analisis untuk mengetahui, apakah kadar gula darah seseorang yang lebih besar dari 120 paling banyak mengalami Heart desease
data$fbs_tabel <- factor(data$fbs, labels = c("≤ 120 mg/dl", "> 120 mg/dl"))
data$target_tabel <- factor(data$target, labels = c("Tidak", "Ya"))

table_fbs <- table(data$fbs_tabel, data$target_tabel)
print(table_fbs)
##              
##               Tidak  Ya
##   ≤ 120 mg/dl   116 142
##   > 120 mg/dl    22  23
prop_fbs <- prop.table(table_fbs, 1)
print(round(prop_fbs, 2))
##              
##               Tidak   Ya
##   ≤ 120 mg/dl  0.45 0.55
##   > 120 mg/dl  0.49 0.51
#Visualisasi perbandingan
library(ggplot2)
ggplot(data, aes(x = fbs_tabel, fill = target_tabel)) +
  geom_bar(position = "fill") +
  scale_y_continuous(labels = scales::percent_format()) +
  labs(title = "Proporsi Heart Disease berdasarkan Kadar Gula Darah",
       x = "Kadar Gula Darah",
       y = "Proporsi",
       fill = "Heart Disease")

  1. Mengidentifikasi untuk mengetahui jenis nyeri dada yang paling banyak terjadi pada seseorang mengalami Heart desease
data$cp_tabel <- factor(data$cp, 
                         levels = c(0,1,2,3),
                         labels = c("Typical angina", 
                                    "Atypical angina", 
                                    "Non-anginal pain", 
                                    "Asymptomatic"))

data$target_tabel <- factor(data$target, labels = c("Tidak", "Ya"))

table_cp <- table(data$cp_tabel, data$target_tabel)
print(table_cp)
##                   
##                    Tidak  Ya
##   Typical angina     104  39
##   Atypical angina      9  41
##   Non-anginal pain    18  69
##   Asymptomatic         7  16
# Visualisasi
library(ggplot2)
ggplot(subset(data, target == 1), aes(x = cp_tabel)) +
  geom_bar(fill = "#E74C3C") +
  labs(title = "Jenis Nyeri Dada pada Penderita Penyakit Jantung",
       x = "Jenis Nyeri Dada",
       y = "Jumlah Penderita")

  1. Visualisasi Bar plot proporsi heart desease terhadap variabel kategorikal cp, ca, dan thal. Interpretasikan
# Label untuk variabel kategorikal
data$target_tabel <- factor(data$target, labels = c("Tidak", "Ya"))
data$cp <- factor(data$cp, labels = c("Typical angina", "Atypical angina", "Non-anginal pain", "Asymptomatic"))
data$thal <- factor(data$thal, labels = c("Unknown", "Fixed defect", "Normal", "Reversible defect"))
data$ca <- as.factor(data$ca)

#cp
library(ggplot2)
ggplot(data, aes(x = cp, fill = target_tabel)) +
  geom_bar(position = "fill") +
  scale_y_continuous(labels = scales::percent) +
  labs(title = "Proporsi Heart Disease berdasarkan Jenis Nyeri Dada (cp)",
       x = "Jenis Nyeri Dada", y = "Proporsi", fill = "Heart Disease") +
  theme_minimal()

#ca
ggplot(data, aes(x = ca, fill = target_tabel)) +
  geom_bar(position = "fill") +
  scale_y_continuous(labels = scales::percent) +
  labs(title = "Proporsi Heart Disease berdasarkan Jumlah Pembuluh Darah (ca)",
       x = "Jumlah Pembuluh Darah", y = "Proporsi", fill = "Heart Disease") +
  theme_minimal()

#thal
ggplot(data, aes(x = thal, fill = target_tabel)) +
  geom_bar(position = "fill") +
  scale_y_continuous(labels = scales::percent) +
  labs(title = "Proporsi Heart Disease berdasarkan Tipe Thalassemia (thal)",
       x = "Tipe Thalassemia", y = "Proporsi", fill = "Heart Disease") +
  theme_minimal()

Interpretasi - cp: Kelompok Atypical angina memiliki proporsi terbesar yang mengalami penyakit jantung. Dan Typical angina lebih banyak pada kelompok yang tidak memiliki penyakit jantung - ca: Makin banyak pembuluh darah (ca = 2 atau 3), proporsi penderita penyakit jantung cenderung lebih rendah. Pembuluh darah 0 dan 4 memiliki proporsi lebih tinggi terkena penyakit jantung -thal: Kondisi Normal cenderung memiliki proporsi tertinggi terkena penyakit jantung. Dan kondisi Reversible defect lebih banyak ditemukan pada yang tidak mengalami penyakit jantung

  1. Melakukan eksplorasi untuk mengetahui arah hubungan antara variabel age dan thalach yang dibedakan untuk seseorang yang memiliki penyakit jantung dan tidak.
library(ggplot2)

data$target_tabel <- factor(data$target, labels = c("Tidak", "Ya"))

ggplot(data, aes(x = age, y = thalach, color = target_tabel)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "lm", se = FALSE) +  # linear trend
  labs(title = "Hubungan antara Age dan Thalach berdasarkan Heart Disease",
       x = "Usia (age)", y = "Detak Jantung Maksimal (thalach)",
       color = "Heart Disease") +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

#Uji Korelasi
# Korelasi keseluruhan
cor(data$age, data$thalach)
## [1] -0.3985219
# Korelasi terpisah
cor(data$age[data$target == 1], data$thalach[data$target == 1])  # Penderita
## [1] -0.5258007
cor(data$age[data$target == 0], data$thalach[data$target == 0])  # Non-penderita
## [1] -0.1327507
# Menentukan Linier atau Non-Linier
# Tambahkan tren non-linear (LOESS)
ggplot(data, aes(x = age, y = thalach, color = target_tabel)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "loess", se = FALSE) +  # untuk mendeteksi pola non-linear
  labs(title = "Hubungan non-linear Age dan Thalach berdasarkan Heart Disease",
       x = "Usia", y = "Detak Jantung Maksimal") +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

  1. Membuat heatmap korelasi antar variabel yang berskala interval atau rasio kemudian interpretasikan hasil yang didapat
selected_data <- data[, c("chol", "trestbps")]
cor_matrix <- cor(selected_data, use = "complete.obs")

library(corrplot)
## Warning: package 'corrplot' was built under R version 4.3.3
## corrplot 0.95 loaded
# Buat heatmap
corrplot(cor_matrix, method = "color", addCoef.col = "black",
         tl.col = "black", title = "Korelasi chol dan trestbps",
         mar = c(0,0,1,0), type = "upper")

Interpretasi: Nilai korelasi antara chol dan trestbps adalah 0.12 . Nilai ini berada dekat 0 yang mengartikan bahwa hubungan antara kadar kolestrol dan tekanan darah sengat lemah dan hampir tidak ada korelasi linier diantara keduanya

  1. Membuat summary hasil analisis yang telah dilakukan Summary hasil analisis data: - Kolestrol dan Penyakit Jantung: tidak ada perbedaan signifikan pada kadar kolestrol antara penderita dan non-penderita penyakit jantung. Dan outliner pada kolestrol dan tekanan darah terdeteksi dan telah ditangani - Jenis Kelamin dan Usia: laki-laki lebih banyak mengalami penyakit jantung dibanding perempuan. Usia yang paling banyak mengalami penyakit jantung berkisar antara 50-60 tahun. Penderita dengan kadar gula darah > 120 mg/dl cenderung berada di rentang usia tua - Gula Darah dan Penyakit Jantung: mayoritas orang dengan gula darah tinggi tidak mengalami penyakit jantung. Artinya gula darah tinggi bukan satu-satunya faktor risiko utama - Jenis Nyeri Dada(cp): Tipe nyeri dada Atypical angina dan Non-angina pain paling umum pada penderita penyakit jantung - Bar plot proporsi penyakit jantung terhadap variabel cp, ca, thal: orang dengan banyak pembuluh darah tersumbat (ca >- 1) lebih rentan terkena penyakit jantung. Kelainan thal tipe 2 dan 3 cenderung berasosiasi dengan penyakit jantung - Hubungan age dan thalach: korelasi negatif: semakin tua usia, detak jantung maksimum cenderung menurun - Korelasi chol dan trestbps: nilai korelasi lemah (0.12) berarti tidak ada hubungan kuat antar keduanya

Hal-hal yang dapat mencegah penyakit jantung: - Menjaga tekanan darah (trestbps) dalam batas normal - Menjaga berat badan dan kolesterol (chol) stabil - Rutin berolahraga → meningkatkan thalach (kapasitas detak jantung maksimum) - Menghindari rokok dan pola makan tinggi lemak - Menjaga kadar gula darah (fbs) dengan pola makan sehat

Aspek apa saja yang merupakan indikasi penyakit jantung: - Jenis kelamin laki-laki - Usia di atas 50 tahun - Jenis nyeri dada tertentu seperti asymptomatic atau non-anginal - Jumlah pembuluh darah (ca) yang mengalami penyumbatan - Kelainan pada thalassemia (thal) - Detak jantung maksimum (thalach) yang rendah

  1. Membuat diagram yang sama dengan contoh. Serta jelaskan maksud setiap dari bagian sintag tersebut. Kemudian interpretasikan
library(ggplot2)

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))
)

# Buat scatter plot dengan garis regresi linier per kategori
ggplot(data, aes(x = Konsumsi_GWh, y = Biaya_per_kWh, color = Konsumen)) +
  geom_point() +  # Titik-titik data
  geom_smooth(method = "lm", se = FALSE) +  # Garis regresi tanpa area kepercayaan
  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"
  ) +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

Syntax - geom_point(): Membuat titik-titik scatter untuk setiap data. - geom_smooth(method = “lm”, se = FALSE): Membuat garis regresi linier untuk setiap kelompok konsumen, tanpa area kepercayaan (confidence interval). - color = Konsumen: Mewarnai titik dan garis berdasarkan kategori konsumen. - theme_minimal(): Tema grafik bersih dan minimalis.

Interpretasi Garis tren untuk semua kategori menurun, yang artinya: Semakin tinggi konsumsi listrik, maka biaya per kWh semakin rendah — hal ini menunjukkan adanya diskon tarif berdasarkan volume penggunaan (biasanya diberikan ke industri besar). Industri memiliki tren biaya per kWh yang paling rendah untuk konsumsi tinggi.