Dataset ini dibuat oleh Manu Parashar dan dapat diakses melalui platform Kaggle. Dataset ini merupakan data sintetis yang dirancang untuk mensimulasikan efisiensi pembakaran kalori manusia secara mendekati realitas (close-to-realistic). Tidak seperti data acak biasa, dataset ini dibangun menggunakan logika fisiologis yang kompleks, di mana efisiensi tidak hanya dihitung dari jumlah kalori yang terbakar, tetapi juga mempertimbangkan intensitas aktivitas, komposisi tubuh, hingga kualitas pemulihan (recovery).
Sistem ini bekerja berdasarkan Logika Biomekanika yang menggunakan rumus rasio antara kalori yang terbakar terhadap volume langkah kaki dan intensitas menit aktif. Terdapat pula Interaksi Variabel yang mempertimbangkan faktor pendukung seperti massa otot, hidrasi, dan durasi tidur, serta faktor penghambat seperti persentase lemak tubuh. Selain itu, dataset ini menyertakan Efek Non-Linear untuk kondisi “Overtraining” dan penalti efisiensi bagi individu yang berolahraga secara berlebihan tanpa istirahat yang cukup. Untuk menjaga aspek Realistik (Noise), terdapat tingkat kesalahan pengukuran sebesar 8% guna mensimulasikan variasi alami manusia atau galat pada perangkat wearable.
library(readxl)
library(dplyr)
library(tidyr)
library(biotools)
library(rstatix)
library(knitr)
library(ggplot2)
df <- read_excel("DATASET KALORI.xlsx")
str(df)
## tibble [100 × 15] (S3: tbl_df/tbl/data.frame)
## $ age : num [1:100] 39 49 38 54 43 38 44 31 62 37 ...
## $ steps_per_day : num [1:100] 5244 8207 4603 4264 1708 ...
## $ active_minutes : num [1:100] 34 88 63 46 13 40 55 24 43 75 ...
## $ calories_burned : num [1:100] 1500 1500 1500 1500 1500 1500 1500 1500 1500 1500 ...
## $ sleep_hours : chr [1:100] "6.63" "7.68" "4.03" "5.55" ...
## $ hydration_liters : chr [1:100] "2.77" "1.84" "0.64" "2.09" ...
## $ bmi : chr [1:100] "25.88" "25.6" "26.99" "26.02" ...
## $ workouts_per_week : num [1:100] 1 1 2 2 1 3 1 2 0 1 ...
## $ muscle_mass_ratio : chr [1:100] "0.366" "0.332" "0.253" "0.398" ...
## $ body_fat_percentage : chr [1:100] "0.355" "0.369" "0.335" "0.254" ...
## $ heart_rate_resting : chr [1:100] "69.4" "68.8" "69.4" "74.1" ...
## $ heart_rate_avg : chr [1:100] "103.0" "117.2" "102.0" "126.4" ...
## $ continuous_exercise_days: num [1:100] 3 2 5 2 7 4 3 7 1 1 ...
## $ efficiency_score : chr [1:100] "1.14" "0.423" "0.715" "0.87" ...
## $ calorie_efficiency : chr [1:100] "Low Efficiency" "Low Efficiency" "Low Efficiency" "Low Efficiency" ...
head(df)
## # A tibble: 6 × 15
## age steps_per_day active_minutes calories_burned sleep_hours
## <dbl> <dbl> <dbl> <dbl> <chr>
## 1 39 5244 34 1500 6.63
## 2 49 8207 88 1500 7.68
## 3 38 4603 63 1500 4.03
## 4 54 4264 46 1500 5.55
## 5 43 1708 13 1500 8.02
## 6 38 6296 40 1500 5.51
## # ℹ 10 more variables: hydration_liters <chr>, bmi <chr>,
## # workouts_per_week <dbl>, muscle_mass_ratio <chr>,
## # body_fat_percentage <chr>, heart_rate_resting <chr>, heart_rate_avg <chr>,
## # continuous_exercise_days <dbl>, efficiency_score <chr>,
## # calorie_efficiency <chr>
kable(head(df, 6), caption = "Preview Data (6 Baris Pertama)")
| age | steps_per_day | active_minutes | calories_burned | sleep_hours | hydration_liters | bmi | workouts_per_week | muscle_mass_ratio | body_fat_percentage | heart_rate_resting | heart_rate_avg | continuous_exercise_days | efficiency_score | calorie_efficiency |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 39 | 5244 | 34 | 1500 | 6.63 | 2.77 | 25.88 | 1 | 0.366 | 0.355 | 69.4 | 103.0 | 3 | 1.14 | Low Efficiency |
| 49 | 8207 | 88 | 1500 | 7.68 | 1.84 | 25.6 | 1 | 0.332 | 0.369 | 68.8 | 117.2 | 2 | 0.423 | Low Efficiency |
| 38 | 4603 | 63 | 1500 | 4.03 | 0.64 | 26.99 | 2 | 0.253 | 0.335 | 69.4 | 102.0 | 5 | 0.715 | Low Efficiency |
| 54 | 4264 | 46 | 1500 | 5.55 | 2.09 | 26.02 | 2 | 0.398 | 0.254 | 74.1 | 126.4 | 2 | 0.87 | Low Efficiency |
| 43 | 1708 | 13 | 1500 | 8.02 | 2.92 | 35.77 | 1 | 0.291 | 0.252 | 75.1 | 108.7 | 7 | 4622 | Moderate |
| 38 | 6296 | 40 | 1500 | 5.51 | 2.59 | 25.26 | 3 | 0.33 | 0.201 | 61.3 | 98.5 | 4 | 1.12 | Low Efficiency |
str(df)
## tibble [100 × 15] (S3: tbl_df/tbl/data.frame)
## $ age : num [1:100] 39 49 38 54 43 38 44 31 62 37 ...
## $ steps_per_day : num [1:100] 5244 8207 4603 4264 1708 ...
## $ active_minutes : num [1:100] 34 88 63 46 13 40 55 24 43 75 ...
## $ calories_burned : num [1:100] 1500 1500 1500 1500 1500 1500 1500 1500 1500 1500 ...
## $ sleep_hours : chr [1:100] "6.63" "7.68" "4.03" "5.55" ...
## $ hydration_liters : chr [1:100] "2.77" "1.84" "0.64" "2.09" ...
## $ bmi : chr [1:100] "25.88" "25.6" "26.99" "26.02" ...
## $ workouts_per_week : num [1:100] 1 1 2 2 1 3 1 2 0 1 ...
## $ muscle_mass_ratio : chr [1:100] "0.366" "0.332" "0.253" "0.398" ...
## $ body_fat_percentage : chr [1:100] "0.355" "0.369" "0.335" "0.254" ...
## $ heart_rate_resting : chr [1:100] "69.4" "68.8" "69.4" "74.1" ...
## $ heart_rate_avg : chr [1:100] "103.0" "117.2" "102.0" "126.4" ...
## $ continuous_exercise_days: num [1:100] 3 2 5 2 7 4 3 7 1 1 ...
## $ efficiency_score : chr [1:100] "1.14" "0.423" "0.715" "0.87" ...
## $ calorie_efficiency : chr [1:100] "Low Efficiency" "Low Efficiency" "Low Efficiency" "Low Efficiency" ...
summary(df)
## age steps_per_day active_minutes calories_burned
## Min. :18.00 Min. : 1000 Min. : 10.00 Min. :1500
## 1st Qu.:32.00 1st Qu.: 4729 1st Qu.: 43.00 1st Qu.:1500
## Median :41.50 Median : 6818 Median : 65.00 Median :1500
## Mean :41.66 Mean : 6554 Mean : 63.21 Mean :1500
## 3rd Qu.:53.25 3rd Qu.: 8223 3rd Qu.: 86.00 3rd Qu.:1500
## Max. :64.00 Max. :12353 Max. :128.00 Max. :1500
## sleep_hours hydration_liters bmi workouts_per_week
## Length:100 Length:100 Length:100 Min. :0.00
## Class :character Class :character Class :character 1st Qu.:1.00
## Mode :character Mode :character Mode :character Median :3.00
## Mean :2.85
## 3rd Qu.:4.00
## Max. :7.00
## muscle_mass_ratio body_fat_percentage heart_rate_resting heart_rate_avg
## Length:100 Length:100 Length:100 Length:100
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
## continuous_exercise_days efficiency_score calorie_efficiency
## Min. :1.00 Length:100 Length:100
## 1st Qu.:1.00 Class :character Class :character
## Median :2.00 Mode :character Mode :character
## Mean :2.74
## 3rd Qu.:4.00
## Max. :7.00
Berdasarkan ringkasan data, variabel calories_burned memiliki nilai konstan (1500) yang menunjukkan tidak adanya variasi. Selain itu, terdapat beberapa variabel numerik yang masih terbaca sebagai character, sehingga diperlukan proses pembersihan tipe data agar dapat dianalisis secara statistik.
# 1. Konversi kolom karakter menjadi numerik & hapus kolom tanpa variasi
df_clean <- df %>%
mutate(across(c(sleep_hours, hydration_liters, bmi, muscle_mass_ratio,
body_fat_percentage, heart_rate_resting, heart_rate_avg,
efficiency_score), as.numeric)) %>%
dplyr::select(-calories_burned) %>%
drop_na()
# 2. Ubah Calorie Efficiency menjadi Faktor
df_clean$calorie_efficiency <- as.factor(df_clean$calorie_efficiency)
# 3. Filter kategori yang jumlahnya terlalu sedikit
df_clean <- df_clean %>%
group_by(calorie_efficiency) %>%
filter(n() >= 3) %>%
ungroup()
print(paste("Jumlah data setelah cleaning:", nrow(df_clean)))
## [1] "Jumlah data setelah cleaning: 100"
str(df_clean)
## tibble [100 × 14] (S3: tbl_df/tbl/data.frame)
## $ age : num [1:100] 39 49 38 54 43 38 44 31 62 37 ...
## $ steps_per_day : num [1:100] 5244 8207 4603 4264 1708 ...
## $ active_minutes : num [1:100] 34 88 63 46 13 40 55 24 43 75 ...
## $ sleep_hours : num [1:100] 6.63 7.68 4.03 5.55 8.02 5.51 5.85 5.48 6.21 6.05 ...
## $ hydration_liters : num [1:100] 2.77 1.84 0.64 2.09 2.92 2.59 1.02 2.12 1.81 4.23 ...
## $ bmi : num [1:100] 25.9 25.6 27 26 35.8 ...
## $ workouts_per_week : num [1:100] 1 1 2 2 1 3 1 2 0 1 ...
## $ muscle_mass_ratio : num [1:100] 0.366 0.332 0.253 0.398 0.291 0.33 0.387 0.528 0.322 0.41 ...
## $ body_fat_percentage : num [1:100] 0.355 0.369 0.335 0.254 0.252 0.201 0.134 0.192 0.259 0.33 ...
## $ heart_rate_resting : num [1:100] 69.4 68.8 69.4 74.1 75.1 61.3 70.8 82.1 62.9 67.1 ...
## $ heart_rate_avg : num [1:100] 103 117 102 126 109 ...
## $ continuous_exercise_days: num [1:100] 3 2 5 2 7 4 3 7 1 1 ...
## $ efficiency_score : num [1:100] 1.14 0.423 0.715 0.87 4622 ...
## $ calorie_efficiency : Factor w/ 3 levels "High Efficiency",..: 2 2 2 2 3 2 2 2 2 2 ...
Proses cleaning berhasil mentransformasi variabel teks menjadi numerik dan menghapus variabel calories_burned yang statis. Penghapusan data kosong (NA) dan filtrasi minimal 3 observasi per grup dilakukan untuk menjamin stabilitas estimasi pada uji Box’s M dan MANCOVA.
ggplot(df_clean, aes(x = calorie_efficiency, y = active_minutes, fill = calorie_efficiency)) +
geom_boxplot() +
theme_minimal() +
labs(title = "Distribusi Menit Aktif berdasarkan Efisiensi Kalori",
x = "Calorie Efficiency", y = "Active Minutes")
> Kelompok Low Efficiency memiliki median menit aktif yang lebih
tinggi dibandingkan kelompok lainnya. Namun, kelompok Moderate
menunjukkan variabilitas (rentang box) yang paling lebar,
mengindikasikan sebaran data yang tidak merata pada kelompok
tersebut.
ggplot(df_clean, aes(x = bmi, y = active_minutes, color = calorie_efficiency)) +
geom_point(alpha = 0.6) +
geom_smooth(method = "lm", se = FALSE) +
theme_minimal() +
labs(title = "Hubungan BMI vs Menit Aktif",
subtitle = "Dibedakan berdasarkan Tingkat Efisiensi Kalori",
x = "BMI", y = "Active Minutes")
## `geom_smooth()` using formula = 'y ~ x'
> Terdapat hubungan linear negatif yang sangat jelas. Semakin tinggi
BMI seseorang, maka jumlah menit aktifnya cenderung menurun. Menariknya,
garis regresi kelompok Moderate (biru) terlihat lebih curam dibandingkan
kelompok lainnya, menunjukkan bahwa pada kelompok ini, kenaikan BMI
berdampak lebih drastis terhadap penurunan menit aktif.
Y_vars <- df_clean[, c("active_minutes", "steps_per_day")]
print("--- Hasil Uji Normalitas Multivariat (M-Shapiro) ---")
## [1] "--- Hasil Uji Normalitas Multivariat (M-Shapiro) ---"
mshapiro_test(Y_vars)
## # A tibble: 1 × 2
## statistic p.value
## <dbl> <dbl>
## 1 0.987 0.432
Hasil uji M-Shapiro menunjukkan p-value 0.432 (> 0.05). Artinya, data berdistribusi normal secara multivariat.
korelasi <- cor.test(df_clean$active_minutes, df_clean$steps_per_day)
print(korelasi)
##
## Pearson's product-moment correlation
##
## data: df_clean$active_minutes and df_clean$steps_per_day
## t = 18.709, df = 98, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
## 0.8319079 0.9205026
## sample estimates:
## cor
## 0.8838958
Nilai korelasi Pearson sebesar 0.883 dengan p-value < 0.05. Ini menunjukkan adanya hubungan positif yang sangat kuat dan signifikan antara active_minutes dan steps_per_day, yang merupakan syarat ideal bagi analisis multivariat.
res_boxm <- boxM(data = Y_vars, group = df_clean$calorie_efficiency)
print(res_boxm)
##
## Box's M-test for Homogeneity of Covariance Matrices
##
## data: Y_vars
## Chi-Sq (approx.) = 5.9901, df = 6, p-value = 0.4243
p-value sebesar 0.424 (> 0.05) menunjukkan bahwa matriks varians-kovarians antar grup adalah homogen (sama). Asumsi terpenuhi.
fit_manova <- manova(cbind(active_minutes, steps_per_day) ~ calorie_efficiency,
data = df_clean)
summary(fit_manova, test = "Wilks")
## Df Wilks approx F num Df den Df Pr(>F)
## calorie_efficiency 2 0.87149 3.4173 4 192 0.01002 *
## Residuals 97
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Nilai Wilks’ Lambda memiliki p-value 0.010 (< 0.05). Artinya, terdapat perbedaan rata-rata gabungan (active_minutes dan steps_per_day) yang signifikan berdasarkan tingkat efisiensi kalori.
fit_mancova <- manova(cbind(active_minutes, steps_per_day) ~ calorie_efficiency + age + bmi,
data = df_clean)
summary(fit_mancova, test = "Wilks")
## Df Wilks approx F num Df den Df Pr(>F)
## calorie_efficiency 2 0.71481 8.591 4 188 2.179e-06 ***
## age 1 0.97055 1.426 2 94 0.2453
## bmi 1 0.33747 92.271 2 94 < 2.2e-16 ***
## Residuals 95
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Ketika variabel kontrol dimasukkan, nilai p-value pada calorie_efficiency turun drastis menjadi 2.179e-06. BMI adalah faktor yang sangat signifikan (p < 2e-16) dalam mempengaruhi aktivitas fisik. Age tidak berpengaruh signifikan (p = 0.245) terhadap aktivitas fisik dalam model ini. Maka kesimpulannya adalah setelah mengontrol faktor BMI, perbedaan efisiensi kalori antar kelompok menjadi jauh lebih nyata.
summary.aov(fit_manova)
## Response active_minutes :
## Df Sum Sq Mean Sq F value Pr(>F)
## calorie_efficiency 2 7846 3923 5.6856 0.004625 **
## Residuals 97 66929 690
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Response steps_per_day :
## Df Sum Sq Mean Sq F value Pr(>F)
## calorie_efficiency 2 74897040 37448520 6.2433 0.002815 **
## Residuals 97 581821049 5998155
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
calorie_efficiency berpengaruh signifikan terhadap kedua variabel dependen: menit aktif (p = 0.004) dan jumlah langkah (p = 0.002).
ancova_active <- aov(active_minutes ~ calorie_efficiency + age + bmi, data = df_clean)
print("--- Hasil ANCOVA: Active Minutes ---")
## [1] "--- Hasil ANCOVA: Active Minutes ---"
summary(ancova_active)
## Df Sum Sq Mean Sq F value Pr(>F)
## calorie_efficiency 2 7846 3923 10.572 7.15e-05 ***
## age 1 608 608 1.638 0.204
## bmi 1 31069 31069 83.725 1.08e-14 ***
## Residuals 95 35252 371
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Setelah BMI dikontrol, pengaruh efisiensi kalori terhadap menit aktif menjadi sangat kuat (p = 7.15e-05). BMI sendiri memberikan kontribusi yang sangat besar terhadap variasi menit aktif.
ancova_steps <- aov(steps_per_day ~ calorie_efficiency + age + bmi, data = df_clean)
print("--- Hasil ANCOVA: Steps Per Day ---")
## [1] "--- Hasil ANCOVA: Steps Per Day ---"
summary(ancova_steps)
## Df Sum Sq Mean Sq F value Pr(>F)
## calorie_efficiency 2 74897040 37448520 17.972 2.4e-07 ***
## age 1 99456 99456 0.048 0.828
## bmi 1 383769977 383769977 184.177 < 2e-16 ***
## Residuals 95 197951616 2083701
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Hasil serupa ditemukan pada jumlah langkah. Efisiensi kalori sangat signifikan (p = 2.4e-07) ketika pengaruh BMI diperhitungkan.
Analisis ini membuktikan bahwa Calorie Efficiency bukan satu-satunya penentu aktivitas fisik. BMI (Body Mass Index) berperan sebagai variabel “pengganggu” yang sangat kuat. Model MANCOVA menunjukkan bahwa jika kita menyamakan level BMI dan usia subjek, perbedaan performa fisik (langkah dan menit aktif) antar tingkat efisiensi kalori akan terlihat jauh lebih kontras dan signifikan. Dalam konteks dataset ini, usia tidak menjadi penghambat aktivitas fisik, namun komposisi tubuh (BMI) dan efisiensi metabolisme adalah kunci utamanya.