Dataset yang digunakan pada tugas ini adalah Diabetes Risk Prediction Dataset, yang diunduh dari Kaggle melalui tautan berikut:
https://www.kaggle.com/datasets/mansiaggarwal88/diabetes-risk-prediction
Dataset ini bersifat sintetis (buatan/simulasi, bukan data pasien sungguhan) dan berfokus pada bidang kesehatan, khususnya prediksi risiko diabetes. Dataset terdiri dari 15.000 baris (pasien) dan 19 kolom, yang mencakup:
age,
gender, city, income_bracketbmi,
physical_activity_level, diet_type,
smoking_status, alcohol_consumption,
hours_sleep_per_night, stress_levelfasting_blood_sugar,
hba1c_level, blood_pressure_systolic,
blood_pressure_diastolic,
waist_circumference_cmdiabetes_risk (Low /
Moderate / High)Kelompok kami memilih dataset ini karena beberapa alasan:
alcohol_consumption dan income_bracket,
sehingga bisa menjadi latihan tambahan dalam eksplorasi data nyata.glimpse(df)
## Rows: 15,000
## Columns: 19
## $ patient_id <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14…
## $ age <dbl> 47, 53, 47, 41, 57, 58, 42, 42, 57, 44, 51, 3…
## $ gender <chr> "Female", "Female", "Male", "Male", "Female",…
## $ city <chr> "Mumbai", "Mumbai", "Thane", "Bengaluru", "Be…
## $ bmi <dbl> 26.5, 20.5, 31.3, 22.8, 16.7, 22.0, 22.5, 19.…
## $ family_history_diabetes <chr> "Yes", "Yes", "No", "No", "No", "No", "No", "…
## $ physical_activity_level <chr> "Sedentary", "Moderate", "Moderate", "Sedenta…
## $ diet_type <chr> "Vegetarian", "Vegetarian", "Non-Vegetarian",…
## $ smoking_status <chr> "Never", "Never", "Current", "Never", "Curren…
## $ alcohol_consumption <chr> "Never", "Never", "Regular", "Never", "Occasi…
## $ hours_sleep_per_night <dbl> 9.0, 7.0, 7.0, 9.0, 6.5, 6.9, 7.0, 6.0, 4.8, …
## $ stress_level <dbl> 8, 6, 7, 5, 10, 6, 10, 7, 10, 8, 2, 6, 4, 9, …
## $ fasting_blood_sugar <dbl> 178, 152, 168, 155, 188, 148, 190, 270, 186, …
## $ hba1c_level <dbl> 7.3, 6.9, 6.6, 6.7, 6.7, 6.3, 7.5, 8.9, 7.4, …
## $ blood_pressure_systolic <dbl> 146, 156, 150, 126, 130, 148, 140, 136, 170, …
## $ blood_pressure_diastolic <dbl> 90, 100, 102, 92, 90, 100, 81, 80, 91, 90, 80…
## $ waist_circumference_cm <dbl> 107.1, 93.8, 113.5, 109.6, 80.8, 98.0, 95.0, …
## $ income_bracket <chr> "High", "Low", "Low", "Middle", "High", "High…
## $ diabetes_risk <chr> "Low", "Low", "High", "Low", "Low", "Low", "M…
colSums(is.na(df))
## patient_id age gender
## 0 0 0
## city bmi family_history_diabetes
## 0 0 0
## physical_activity_level diet_type smoking_status
## 0 0 472
## alcohol_consumption hours_sleep_per_night stress_level
## 3788 0 0
## fasting_blood_sugar hba1c_level blood_pressure_systolic
## 0 0 0
## blood_pressure_diastolic waist_circumference_cm income_bracket
## 0 0 463
## diabetes_risk
## 0
Terlihat bahwa terdapat data yang hilang (missing value)
pada kolom smoking_status,
alcohol_consumption, dan income_bracket. Untuk
visualisasi kategorik terkait kolom ini, nilai NA akan
ditampilkan sebagai kategori tersendiri agar proporsinya tetap
terlihat.
ggplot(df, aes(x = fct_infreq(diabetes_risk), fill = diabetes_risk)) +
geom_bar() +
geom_text(stat = "count", aes(label = comma(after_stat(count))), vjust = -0.4) +
labs(title = "Distribusi Kategori Risiko Diabetes",
x = "Kategori Risiko Diabetes", y = "Jumlah Pasien") +
theme_minimal() +
theme(legend.position = "none")
Interpretasi: Sebagian besar pasien dalam dataset (sekitar 9.000 dari 15.000 pasien, atau 60%) berada pada kategori risiko Low, diikuti oleh Moderate (25%) dan High (15%). Ini menunjukkan bahwa data tidak seimbang (imbalanced) antar kelas, yang perlu diperhatikan apabila dataset ini digunakan untuk membangun model klasifikasi.
gender_df <- df %>%
count(gender) %>%
mutate(pct = n / sum(n))
ggplot(gender_df, aes(x = "", y = n, fill = gender)) +
geom_col(width = 1, color = "white") +
coord_polar(theta = "y") +
geom_text(aes(label = percent(pct, accuracy = 0.1)), position = position_stack(vjust = 0.5)) +
labs(title = "Proporsi Jenis Kelamin Pasien", fill = "Gender") +
theme_void()
Interpretasi: Proporsi pasien laki-laki (Male) sedikit lebih banyak dibandingkan perempuan (Female), masing-masing sekitar 51% dan 48%, sementara kategori “Other” hanya mewakili sebagian kecil (~1%) dari total data. Secara umum, distribusi jenis kelamin dalam dataset ini cukup seimbang.
ggplot(df, aes(x = fct_infreq(diet_type))) +
geom_bar(fill = "#2E8B57") +
labs(title = "Distribusi Tipe Diet Pasien", x = "Tipe Diet", y = "Jumlah Pasien") +
theme_minimal()
Interpretasi: Mayoritas pasien menerapkan pola makan Non-Vegetarian (sekitar 55%), diikuti Vegetarian (sekitar 40%), sementara Pescatarian dan Vegan hanya mewakili sebagian kecil pasien. Hal ini mencerminkan pola konsumsi masyarakat India secara umum, sesuai konteks data.
ggplot(df, aes(x = family_history_diabetes, fill = diabetes_risk)) +
geom_bar(position = "fill") +
scale_y_continuous(labels = percent) +
labs(title = "Proporsi Risiko Diabetes berdasarkan Riwayat Keluarga",
x = "Riwayat Keluarga Diabetes", y = "Proporsi", fill = "Risiko Diabetes") +
theme_minimal()
Interpretasi: Pasien dengan riwayat keluarga diabetes (“Yes”) memiliki proporsi risiko High dan Moderate yang lebih besar (sekitar 20% dan 31%) dibandingkan pasien tanpa riwayat keluarga (sekitar 12% dan 22%). Ini mengindikasikan bahwa faktor genetik/riwayat keluarga berkaitan dengan peningkatan risiko diabetes pada dataset ini.
ggplot(df, aes(x = fct_relevel(physical_activity_level, "Sedentary", "Moderate", "Active"),
fill = diabetes_risk)) +
geom_bar(position = "fill") +
scale_y_continuous(labels = percent) +
labs(title = "Proporsi Risiko Diabetes berdasarkan Tingkat Aktivitas Fisik",
x = "Tingkat Aktivitas Fisik", y = "Proporsi", fill = "Risiko Diabetes") +
theme_minimal()
Interpretasi: Terlihat pola yang jelas — semakin rendah tingkat aktivitas fisik (Sedentary), semakin besar proporsi pasien dengan risiko High (sekitar 21%) dibandingkan pasien yang aktif/Active (sekitar 10%). Ini menunjukkan gaya hidup aktif secara fisik berasosiasi dengan risiko diabetes yang lebih rendah.
ggplot(df, aes(x = age)) +
geom_histogram(binwidth = 5, fill = "#4C72B0", color = "white") +
labs(title = "Distribusi Usia Pasien", x = "Usia (tahun)", y = "Frekuensi") +
theme_minimal()
Interpretasi: Usia pasien tersebar cukup merata di rentang dewasa, dengan rata-rata sekitar 44 tahun dan mayoritas berada pada rentang 35–55 tahun. Bentuk distribusi mendekati simetris/normal tanpa penumpukan ekstrem di salah satu ujung.
ggplot(df, aes(x = bmi)) +
geom_histogram(binwidth = 1, fill = "#DD8452", color = "white") +
geom_vline(aes(xintercept = mean(bmi)), color = "red", linetype = "dashed") +
labs(title = "Distribusi BMI Pasien (garis merah = rata-rata)",
x = "BMI", y = "Frekuensi") +
theme_minimal()
Interpretasi: Rata-rata BMI pasien berada di angka sekitar 23, yang menurut standar umum masuk kategori berat badan normal/sedikit di atas normal. Distribusi sedikit menjulur ke kanan (right-skewed), menandakan ada sebagian kecil pasien dengan BMI cukup tinggi (obesitas).
ggplot(df, aes(x = diabetes_risk, y = bmi, fill = diabetes_risk)) +
geom_boxplot() +
labs(title = "Sebaran BMI berdasarkan Kategori Risiko Diabetes",
x = "Kategori Risiko Diabetes", y = "BMI") +
theme_minimal() +
theme(legend.position = "none")
Interpretasi: Median BMI meningkat seiring meningkatnya kategori risiko diabetes: pasien Low memiliki median BMI terendah (~22), sedangkan pasien High memiliki median BMI tertinggi (~25). Ini mengonfirmasi bahwa BMI yang lebih tinggi berasosiasi dengan risiko diabetes yang lebih besar.
ggplot(df, aes(x = diabetes_risk, y = fasting_blood_sugar, fill = diabetes_risk)) +
geom_boxplot() +
labs(title = "Sebaran Gula Darah Puasa berdasarkan Kategori Risiko Diabetes",
x = "Kategori Risiko Diabetes", y = "Fasting Blood Sugar (mg/dL)") +
theme_minimal() +
theme(legend.position = "none")
Interpretasi: Sesuai ekspektasi klinis, kadar gula darah puasa (fasting blood sugar) meningkat secara konsisten dari kategori Low ke High. Hal ini logis karena kadar gula darah puasa memang merupakan salah satu indikator klinis utama dalam menentukan risiko diabetes.
ggplot(df, aes(x = bmi, y = waist_circumference_cm, color = diabetes_risk)) +
geom_point(alpha = 0.3, size = 0.8) +
geom_smooth(method = "lm", se = FALSE, color = "black") +
labs(title = "Hubungan antara BMI dan Lingkar Pinggang",
x = "BMI", y = "Lingkar Pinggang (cm)", color = "Risiko Diabetes") +
theme_minimal()
Interpretasi: Terdapat hubungan positif yang cukup jelas antara BMI dan lingkar pinggang — semakin tinggi BMI, semakin besar lingkar pinggang pasien. Titik-titik dengan warna risiko High juga cenderung berkumpul di area BMI dan lingkar pinggang yang lebih tinggi, memperkuat temuan sebelumnya.
num_vars <- df %>%
select(age, bmi, hours_sleep_per_night, stress_level, fasting_blood_sugar,
hba1c_level, blood_pressure_systolic, blood_pressure_diastolic,
waist_circumference_cm)
corr_matrix <- cor(num_vars, use = "complete.obs")
corrplot(corr_matrix, method = "color", type = "upper",
addCoef.col = "black", number.cex = 0.6, tl.col = "black",
tl.srt = 45, title = "Matriks Korelasi Variabel Numerik", mar = c(0,0,2,0))
Interpretasi: Variabel bmi dan
waist_circumference_cm menunjukkan korelasi positif yang
cukup kuat, begitu juga fasting_blood_sugar dengan
hba1c_level, yang secara klinis masuk akal karena keduanya
sama-sama indikator kadar gula darah. Variabel seperti
hours_sleep_per_night cenderung memiliki korelasi lemah
dengan variabel klinis lain.
Berdasarkan eksplorasi visual terhadap dataset Diabetes Risk Prediction, dapat disimpulkan bahwa:
Dataset ini terbukti cukup representatif untuk latihan visualisasi data kategorik maupun numerik, serta memberikan gambaran awal yang baik mengenai faktor-faktor yang berasosiasi dengan risiko diabetes.