1 Pendahuluan

Laporan ini menyajikan analisis Principal Component Analysis (PCA) dan Factor Analysis (FA) pada dataset Body Performance yang berisi data kebugaran fisik manusia. Kedua metode ini merupakan teknik reduksi dimensi yang bertujuan menemukan struktur tersembunyi dalam data multivariat dengan 10 variabel numerik.

  • PCA bertujuan menemukan kombinasi linier variabel yang memaksimalkan variansi data.
  • FA bertujuan menemukan faktor-faktor laten (tidak teramati) yang menjelaskan pola korelasi antar variabel.

2 Persiapan dan Pembersihan Data

2.1 Load Library

library(tidyverse)
library(corrplot)
library(factoextra)
library(psych)
library(ggplot2)
library(gridExtra)
library(reshape2)

Penjelasan Library:

Library Fungsi
tidyverse Manipulasi dan transformasi data
corrplot Visualisasi matriks korelasi
factoextra Visualisasi hasil PCA (scree plot, biplot, kontribusi)
psych Uji KMO, Bartlett, dan Factor Analysis
ggplot2 Pembuatan grafik
gridExtra Menggabungkan beberapa plot menjadi satu tampilan
reshape2 Transformasi data dari format wide ke long

2.2 Load dan Bersihkan Data

df_raw <- read.csv("body_performance.csv", sep = ";", stringsAsFactors = FALSE)

df_raw$body.fat_. <- as.numeric(df_raw$body.fat_.)
df_clean <- df_raw %>% drop_na()

df_clean <- df_clean %>%
  filter(body.fat_. < 60,
         sit.and.bend.forward_cm < 100)

cat("Dimensi setelah hapus outlier ekstrem:", nrow(df_clean), "baris x", ncol(df_clean), "kolom\n")
## Dimensi setelah hapus outlier ekstrem: 13319 baris x 12 kolom

Penjelasan: Output berupa satu baris teks yang menampilkan jumlah baris (observasi) dan kolom (variabel) yang tersisa setelah proses pembersihan data. Proses pembersihan meliputi:

  1. Konversi tipe data: kolom body.fat_. dikonversi ke numerik karena kemungkinan terbaca sebagai karakter (character) saat import CSV.
  2. Hapus missing values (NA): baris yang memiliki nilai kosong di kolom manapun dihapus menggunakan drop_na().
  3. Filter outlier ekstrem:
    • body_fat >= 60% → tidak realistis secara biologis untuk manusia hidup sehat.
    • sit_bend >= 100 cm → nilai yang terlalu ekstrem dan patut dicurigai sebagai kesalahan input.

Pembersihan ini penting agar hasil analisis tidak terdistorsi oleh nilai-nilai yang tidak wajar.

2.3 Seleksi dan Penamaan Variabel

num_cols <- c("age", "height_cm", "weight_kg", "body.fat_.",
              "diastolic", "systolic", "gripForce",
              "sit.and.bend.forward_cm", "sit.ups.counts", "broad.jump_cm")

X <- df_clean %>% select(all_of(num_cols))

colnames(X) <- c("age", "height_cm", "weight_kg", "body_fat",
                 "diastolic", "systolic", "gripForce",
                 "sit_bend", "sit_ups", "broad_jump")

Penjelasan: Dipilih 10 variabel numerik yang merepresentasikan kondisi fisik responden. Nama kolom disederhanakan agar lebih mudah dibaca pada grafik dan output.

Variabel Baru Keterangan Satuan
age Usia tahun
height_cm Tinggi badan cm
weight_kg Berat badan kg
body_fat Persentase lemak tubuh %
diastolic Tekanan darah diastolik mmHg
systolic Tekanan darah sistolik mmHg
gripForce Kekuatan genggaman tangan kg
sit_bend Fleksibilitas duduk & membungkuk cm
sit_ups Jumlah sit-up kali
broad_jump Lompat jauh tanpa awalan cm

3 Statistik Deskriptif

desc_stats <- data.frame(
  Variabel = colnames(X),
  N        = sapply(X, function(x) sum(!is.na(x))),
  Mean     = round(sapply(X, mean, na.rm = TRUE), 2),
  SD       = round(sapply(X, sd,   na.rm = TRUE), 2),
  Min      = round(sapply(X, min,  na.rm = TRUE), 2),
  Q1       = round(sapply(X, quantile, probs = 0.25, na.rm = TRUE), 2),
  Median   = round(sapply(X, median, na.rm = TRUE), 2),
  Q3       = round(sapply(X, quantile, probs = 0.75, na.rm = TRUE), 2),
  Max      = round(sapply(X, max,  na.rm = TRUE), 2)
)
print(desc_stats)
##              Variabel     N   Mean    SD   Min    Q1 Median     Q3   Max
## age               age 13319  36.77 13.62  21.0  25.0   32.0  48.00  64.0
## height_cm   height_cm 13319 168.57  8.43 125.0 162.4  169.2 174.80 193.8
## weight_kg   weight_kg 13319  67.46 11.95  26.3  58.2   67.5  75.38 138.1
## body_fat     body_fat 13319  23.24  7.24   3.0  18.0   22.8  28.00  54.9
## diastolic   diastolic 13319  78.78 10.75   0.0  71.0   79.0  86.00 156.2
## systolic     systolic 13319 130.21 14.71   0.0 120.0  130.0 141.00 201.0
## gripForce   gripForce 13319  36.96 10.63   0.0  27.5   37.9  45.20  70.5
## sit_bend     sit_bend 13319  15.16  8.14 -25.0  10.9   16.2  20.70  42.0
## sit_ups       sit_ups 13319  39.76 14.27   0.0  30.0   41.0  50.00  80.0
## broad_jump broad_jump 13319 190.14 39.88   0.0 162.0  193.0 221.00 303.0

Penjelasan: Tabel statistik deskriptif merangkum karakteristik dasar setiap variabel:

  • N: jumlah observasi valid (tidak termasuk NA).
  • Mean: nilai rata-rata — gambaran “pusat” distribusi data.
  • SD (Standar Deviasi): seberapa besar data menyebar dari rata-rata. SD besar = variasi antar individu tinggi.
  • Min & Max: nilai paling kecil dan paling besar yang tercatat.
  • Q1 (Kuartil 1): 25% data berada di bawah nilai ini.
  • Median (Q2): nilai tengah data; lebih tahan terhadap outlier dibanding mean.
  • Q3 (Kuartil 3): 75% data berada di bawah nilai ini.

Hal penting yang diperhatikan: Perbedaan satuan dan skala antar variabel (misalnya age dalam satuan tahun vs broad_jump dalam cm) menjadi alasan utama mengapa data harus distandarisasi sebelum dilakukan PCA dan FA. Tanpa standardisasi, variabel dengan skala besar akan mendominasi hasil analisis.


4 Eksplorasi Data (EDA)

4.1 Distribusi Variabel Kunci

p1 <- ggplot(X, aes(x = age)) +
  geom_histogram(bins = 40, fill = "#2E75B6", color = "white", alpha = 0.85) +
  labs(title = "Distribusi Usia", x = "Usia (tahun)", y = "Frekuensi") +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"))

p2 <- ggplot(X, aes(x = body_fat)) +
  geom_histogram(bins = 40, fill = "#E74C3C", color = "white", alpha = 0.85) +
  labs(title = "Distribusi Body Fat (%)", x = "Body Fat (%)", y = "Frekuensi") +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"))

p3 <- ggplot(X, aes(x = gripForce)) +
  geom_histogram(bins = 40, fill = "#27AE60", color = "white", alpha = 0.85) +
  labs(title = "Distribusi Grip Force", x = "Grip Force (kg)", y = "Frekuensi") +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"))

p4 <- ggplot(X, aes(x = broad_jump)) +
  geom_histogram(bins = 40, fill = "#8E44AD", color = "white", alpha = 0.85) +
  labs(title = "Distribusi Broad Jump", x = "Broad Jump (cm)", y = "Frekuensi") +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"))

grid.arrange(p1, p2, p3, p4, nrow = 2, top = "Distribusi Variabel Kunci")

Penjelasan : Empat histogram menampilkan sebaran frekuensi variabel-variabel kunci:

  • Usia: distribusi miring ke kanan (right-skewed) — lebih banyak responden berusia muda. Ini wajar karena populasi yang aktif berolahraga umumnya lebih muda.
  • Body Fat (%): mendekati distribusi normal dengan puncak di kisaran 15–25%. Distribusi cukup simetris.
  • Grip Force: terlihat dua puncak (bimodal) — kemungkinan besar mencerminkan perbedaan kekuatan antara laki-laki (nilai lebih tinggi) dan perempuan (nilai lebih rendah).
  • Broad Jump: distribusi mendekati normal, sedikit miring. Variasi antar individu cukup besar.

Pola bimodal pada Grip Force dan Broad Jump mengindikasikan adanya pengaruh jenis kelamin yang cukup signifikan dalam data kebugaran fisik ini.

4.2 Matriks Korelasi

cor_matrix <- cor(X)
corrplot(cor_matrix, method = "color", tl.cex = 0.75,
         addCoef.col = "black", number.cex = 0.6,
         title = "Matriks Korelasi Antar Variabel", mar = c(0,0,1,0))

Penjelasan : Matriks korelasi menampilkan nilai korelasi Pearson (−1 hingga +1) antara setiap pasang variabel:

-Biru gelap = korelasi positif kuat → kedua variabel naik bersama-sama. -Merah gelap = korelasi negatif kuat → satu naik, yang lain turun. -*Putih/pucat** = korelasi lemah atau tidak ada hubungan linier.

Pola korelasi yang terlihat: - gripForce, broad_jump, sit_ups → berkorelasi positif satu sama lain → ketiganya mengukur kebugaran fisik aktif. - body_fat → berkorelasi negatif dengan variabel kebugaran aktif → semakin tinggi lemak tubuh, semakin rendah performa fisik. - age → berkorelasi negatif dengan variabel performa fisik → performa menurun seiring bertambahnya usia. - systolic dan diastolic → berkorelasi positif kuat → keduanya adalah ukuran tekanan darah yang bergerak bersama.

Adanya korelasi yang signifikan antar variabel merupakan syarat utama agar PCA dan FA dapat diterapkan secara bermakna.

4.3 Boxplot Variabel Terstandarisasi

X_scaled_df <- as.data.frame(scale(X))
X_melt      <- melt(X_scaled_df)

ggplot(X_melt, aes(x = variable, y = value, fill = variable)) +
  geom_boxplot(alpha = 0.75, outlier.size = 0.5, outlier.alpha = 0.3) +
  labs(title = "Boxplot Variabel (Standardisasi Z-Score)",
       x = "Variabel", y = "Nilai Terstandarisasi (Z-Score)") +
  theme_minimal(base_size = 11) +
  theme(legend.position = "none",
        axis.text.x = element_text(angle = 45, hjust = 1),
        plot.title  = element_text(face = "bold"))

Penjelasan: Boxplot ini menampilkan distribusi setiap variabel setelah distandarisasi menggunakan Z-Score (mean = 0, SD = 1). Standardisasi dilakukan agar semua variabel berada pada skala yang sama sehingga perbandingan menjadi adil.

Cara membaca boxplot: - Kotak (IQR): rentang antara Q1 (25%) dan Q3 (75%). - Garis tengah dalam kotak: nilai median (Q2). - Whisker (garis panjang): rentang data di luar IQR (biasanya ±1.5 × IQR). - Titik-titik kecil di luar whisker: outlier.

Setelah standardisasi, semua variabel berpusat di angka 0. Boxplot ini membantu mengidentifikasi apakah ada variabel dengan banyak outlier, yang bisa memengaruhi hasil analisis.


5 Uji Asumsi

Sebelum melakukan PCA dan FA, perlu dilakukan dua uji kelayakan untuk memastikan data cocok dianalisis dengan kedua metode ini.

5.1 Uji KMO (Kaiser-Meyer-Olkin)

kmo_result <- KMO(X)
print(kmo_result)
## Kaiser-Meyer-Olkin factor adequacy
## Call: KMO(r = X)
## Overall MSA =  0.73
## MSA for each item = 
##        age  height_cm  weight_kg   body_fat  diastolic   systolic  gripForce 
##       0.64       0.77       0.60       0.61       0.60       0.64       0.84 
##   sit_bend    sit_ups broad_jump 
##       0.67       0.83       0.88

Penjelasan: Uji KMO mengukur kecukupan sampling — seberapa tepat data untuk dianalisis menggunakan FA/PCA. KMO membandingkan korelasi langsung antar variabel dengan korelasi parsialnya.

Interpretasi nilai KMO:

Nilai KMO Kategori
≥ 0.90 Sangat Baik (Marvelous)
0.80 – 0.89 Baik (Meritorious)
0.70 – 0.79 Cukup (Middling)
0.60 – 0.69 Biasa (Mediocre)
< 0.50 Tidak layak

Output menampilkan: - Overall MSA: nilai KMO keseluruhan → harus ≥ 0.70 agar data layak. - MSA per variabel: nilai KMO untuk masing-masing variabel. Variabel dengan MSA < 0.50 sebaiknya dikeluarkan dari analisis.

5.2 Uji Bartlett

bart_result <- cortest.bartlett(X)
print(bart_result)
## $chisq
## [1] 83465.15
## 
## $p.value
## [1] 0
## 
## $df
## [1] 45

Penjelasan: Uji Bartlett menguji apakah matriks korelasi secara signifikan berbeda dari matriks identitas (matriks yang semua korelasi antar variabelnya = 0).

  • H₀ (Hipotesis Nol): matriks korelasi = matriks identitas → tidak ada korelasi antar variabel → FA/PCA tidak layak.
  • H₁ (Hipotesis Alternatif): matriks korelasi ≠ matriks identitas → ada korelasi signifikan → FA/PCA layak.

Keputusan: Jika p-value < 0.05, tolak H₀ → data memiliki korelasi yang cukup → layak untuk PCA dan FA.

Output menampilkan nilai chi-square, degrees of freedom (df), dan p-value.


6 Principal Component Analysis (PCA)

PCA adalah teknik untuk mengubah variabel-variabel yang saling berkorelasi menjadi sekumpulan variabel baru yang tidak berkorelasi, disebut Principal Components (PC). Setiap PC merupakan kombinasi linier dari variabel asli.

6.1 Eksekusi PCA

X_scaled   <- scale(X)
pca_result <- prcomp(X_scaled, center = FALSE, scale. = FALSE)
print(summary(pca_result))
## Importance of components:
##                           PC1    PC2    PC3     PC4    PC5     PC6    PC7
## Standard deviation     2.0449 1.4361 1.1018 0.88886 0.8019 0.56348 0.5514
## Proportion of Variance 0.4182 0.2062 0.1214 0.07901 0.0643 0.03175 0.0304
## Cumulative Proportion  0.4182 0.6244 0.7458 0.82479 0.8891 0.92084 0.9513
##                            PC8     PC9    PC10
## Standard deviation     0.46341 0.41725 0.31410
## Proportion of Variance 0.02148 0.01741 0.00987
## Cumulative Proportion  0.97272 0.99013 1.00000

Penjelasan: summary(pca_result) menghasilkan tiga baris penting untuk setiap PC:

  • Standard deviation: akar dari eigenvalue. Semakin besar nilainya, semakin banyak variansi yang ditangkap PC tersebut.
  • Proportion of Variance: proporsi variansi total yang dijelaskan oleh satu PC. Misalnya, 0.35 artinya PC tersebut menjelaskan 35% variansi data.
  • Cumulative Proportion: variansi kumulatif dari PC1 hingga PC ke-n. Target umum adalah mencapai ≥ 70–80% variansi kumulatif.

PC1 selalu menjelaskan variansi terbesar, diikuti PC2, PC3, dan seterusnya yang semakin mengecil.

6.2 Tabel Eigenvalue dan Variansi

eigenvalues   <- pca_result$sdev^2
var_explained <- eigenvalues / sum(eigenvalues) * 100
cum_var       <- cumsum(var_explained)

pca_summary <- data.frame(
  PC           = paste0("PC", 1:10),
  Eigenvalue   = round(eigenvalues, 4),
  Variansi_pct = round(var_explained, 2),
  Variansi_Kum = round(cum_var, 2)
)
print(pca_summary)
##      PC Eigenvalue Variansi_pct Variansi_Kum
## 1   PC1     4.1815        41.81        41.81
## 2   PC2     2.0623        20.62        62.44
## 3   PC3     1.2140        12.14        74.58
## 4   PC4     0.7901         7.90        82.48
## 5   PC5     0.6430         6.43        88.91
## 6   PC6     0.3175         3.18        92.08
## 7   PC7     0.3040         3.04        95.12
## 8   PC8     0.2148         2.15        97.27
## 9   PC9     0.1741         1.74        99.01
## 10 PC10     0.0987         0.99       100.00

Penjelasan: Tabel ini merangkum tiga informasi penting setiap PC:

  • Eigenvalue: besarnya variansi yang ditangkap oleh sebuah PC. Berdasarkan Kriteria Kaiser, hanya PC dengan eigenvalue > 1 yang dianggap bermakna dan layak dipertahankan. Eigenvalue = 1 artinya PC tersebut hanya menjelaskan variansi sebesar satu variabel — tidak ada nilai tambah dibanding variabel aslinya.
  • Variansi_pct: persentase variansi per PC secara individual.
  • Variansi_Kum: akumulasi persentase variansi. Gunakan ini untuk menentukan berapa PC yang cukup untuk merangkum data.

PC yang dipilih adalah PC-PC pertama hingga variansi kumulatif mencapai ≥ 80%.

6.3 Scree Plot PCA

fviz_eig(pca_result,
         addlabels = TRUE,
         ylim      = c(0, 50),
         barfill   = "#2E75B6",
         barcolor  = "white",
         linecolor = "#E74C3C",
         main      = "Scree Plot PCA",
         xlab      = "Principal Component",
         ylab      = "Persentase Variansi yang Dijelaskan (%)")

Penjelasan: Scree Plot adalah alat visual utama untuk menentukan jumlah PC yang optimal:

  • Batang biru: persentase variansi yang dijelaskan setiap PC secara individual.
  • Garis merah: menghubungkan titik-titik antar PC untuk melihat tren penurunan.
  • Angka di atas batang: persentase variansi yang tepat.

Cara menentukan jumlah PC dari Scree Plot: Cari titik di mana kurva mulai “melandai datar” — disebut elbow point (titik siku). PC sebelum titik siku inilah yang sebaiknya dipertahankan karena setelah titik tersebut, penambahan PC tidak banyak menambah informasi baru.

6.4 Grafik Variansi Kumulatif

ggplot(pca_summary, aes(x = as.numeric(gsub("PC", "", PC)))) +
  geom_col(aes(y = Variansi_pct), fill = "#2E75B6", alpha = 0.8) +
  geom_line(aes(y = Variansi_Kum), color = "#E74C3C", size = 1.2) +
  geom_point(aes(y = Variansi_Kum), color = "#E74C3C", size = 3) +
  geom_hline(yintercept = 80, linetype = "dashed", color = "#27AE60", size = 1) +
  annotate("text", x = 9.5, y = 82, label = "80%", color = "#27AE60", fontface = "bold") +
  scale_x_continuous(breaks = 1:10, labels = paste0("PC", 1:10)) +
  labs(title = "Variansi Kumulatif PCA",
       x = "Principal Component", y = "Variansi (%)") +
  theme_minimal(base_size = 11) +
  theme(plot.title  = element_text(face = "bold"),
        axis.text.x = element_text(angle = 45, hjust = 1))

Penjelasan : Grafik ini menggabungkan dua informasi sekaligus:

  • Batang biru: kontribusi variansi masing-masing PC (individual).
  • Garis + titik merah: variansi kumulatif yang terus meningkat.
  • Garis hijau putus-putus: ambang batas 80% variansi kumulatif.

Cara membaca: Lihat di PC ke berapa garis merah pertama kali menyentuh atau melewati garis hijau 80%. PC pertama hingga PC tersebut adalah komponen yang direkomendasikan untuk dipertahankan dalam analisis lebih lanjut.

6.5 Loading Matrix PCA

loadings_pca <- as.data.frame(pca_result$rotation[, 1:4])
colnames(loadings_pca) <- c("PC1", "PC2", "PC3", "PC4")
print(round(loadings_pca, 3))
##               PC1    PC2    PC3    PC4
## age         0.208 -0.378  0.050 -0.748
## height_cm  -0.421 -0.077 -0.235 -0.045
## weight_kg  -0.337 -0.301 -0.319  0.164
## body_fat    0.331 -0.241 -0.174  0.534
## diastolic  -0.106 -0.506  0.404  0.250
## systolic   -0.143 -0.518  0.380  0.067
## gripForce  -0.432 -0.095 -0.056 -0.193
## sit_bend    0.047  0.285  0.668  0.011
## sit_ups    -0.378  0.267  0.216  0.142
## broad_jump -0.439  0.130  0.082 -0.047

Penjelasan : Loading matrix adalah inti dari interpretasi PCA. Setiap nilai dalam tabel menunjukkan seberapa besar dan ke arah mana sebuah variabel berkontribusi terhadap sebuah PC.

  • Nilai loading berkisar antara −1 hingga +1.
  • Loading positif tinggi (≥ 0.4): variabel berkontribusi besar searah dengan PC → individu dengan nilai PC tinggi juga memiliki nilai variabel ini yang tinggi.
  • Loading negatif tinggi (≤ −0.4): variabel berkontribusi besar berlawanan arah.
  • Loading mendekati 0: variabel tidak banyak membentuk PC tersebut.

Dari loading matrix, kita bisa menamai setiap PC berdasarkan variabel-variabel dominan yang membentuknya. Misalnya, jika PC1 memiliki loading tinggi pada gripForce, sit_ups, dan broad_jump, maka PC1 dapat diinterpretasikan sebagai “Komponen Kebugaran Aktif”.

6.6 Heatmap Loading PCA

load_melt <- melt(as.matrix(loadings_pca))
colnames(load_melt) <- c("Variabel", "Komponen", "Loading")

ggplot(load_melt, aes(x = Komponen, y = Variabel, fill = Loading)) +
  geom_tile(color = "white") +
  geom_text(aes(label = round(Loading, 2)), size = 3.5, fontface = "bold") +
  scale_fill_gradient2(low = "#D73027", mid = "white", high = "#1A6FBA",
                       midpoint = 0, limits = c(-1, 1)) +
  labs(title = "Heatmap Loading Matrix PCA",
       x = "Komponen Utama", y = "Variabel", fill = "Loading") +
  theme_minimal(base_size = 11) +
  theme(plot.title  = element_text(face = "bold"),
        axis.text.y = element_text(size = 10))

Penjelasan : Heatmap adalah representasi visual dari loading matrix — lebih mudah dibaca dibanding deretan angka. Setiap sel menampilkan warna dan angka loading:

  • Biru gelap: loading positif kuat → variabel sangat berpengaruh pada PC tersebut (arah positif).
  • Merah gelap: loading negatif kuat → variabel sangat berpengaruh pada PC tersebut (arah negatif).
  • Putih: loading mendekati nol → variabel tidak relevan untuk PC tersebut.

Dengan heatmap, pola “pengelompokan” variabel per PC lebih mudah terlihat secara intuitif. Idealnya, setiap PC memiliki beberapa variabel dengan warna gelap (loading tinggi) dan sisanya berwarna putih (loading rendah).

6.7 Biplot PCA (PC1 vs PC2)

fviz_pca_biplot(pca_result,
                geom.ind   = "point",
                pointshape = 21,
                pointsize  = 1.5,
                fill.ind   = "#AED6F1",
                col.ind    = "transparent",
                col.var    = "#E74C3C",
                arrowsize  = 0.8,
                repel      = TRUE,
                alpha.ind  = 0.3,
                title      = "Biplot PCA (PC1 vs PC2)")

Penjelasan : Biplot menggabungkan dua informasi dalam satu grafik pada bidang PC1–PC2:

1. Titik-titik (individu/observasi): - Setiap titik mewakili satu responden. - Titik yang berdekatan → profil kebugaran fisik yang mirip. - Titik yang berjauhan → profil yang berbeda secara signifikan.

2. Panah merah (variabel): - Panjang panah: semakin panjang → variabel semakin baik direpresentasikan dalam bidang PC1–PC2. - Arah panah yang sama → kedua variabel berkorelasi positif. - Arah panah berlawanan → kedua variabel berkorelasi negatif. - Arah panah tegak lurus → kedua variabel tidak berkorelasi. - Individu yang berada searah dengan sebuah panah → memiliki nilai tinggi untuk variabel tersebut.

6.8 Kontribusi Variabel ke PC1 dan PC2

contrib_pc1 <- fviz_contrib(pca_result, choice = "var", axes = 1,
                            fill  = "#2E75B6", color = "white",
                            title = "Kontribusi Variabel ke PC1")

contrib_pc2 <- fviz_contrib(pca_result, choice = "var", axes = 2,
                            fill  = "#E74C3C", color = "white",
                            title = "Kontribusi Variabel ke PC2")

grid.arrange(contrib_pc1, contrib_pc2, nrow = 1,
             top = "Kontribusi Variabel ke PC1 dan PC2")

Penjelasan : Grafik batang ini menunjukkan persentase kontribusi setiap variabel dalam membentuk PC1 (biru) dan PC2 (merah):

  • Garis putus-putus merah horizontal: ambang rata-rata kontribusi = 100% / jumlah variabel = 10% (untuk 10 variabel). Variabel yang melampaui garis ini dianggap berkontribusi signifikan terhadap PC tersebut.
  • Variabel dengan batang tertinggi adalah variabel yang paling dominan mendefinisikan PC tersebut.

Grafik ini melengkapi loading matrix dengan menunjukkan secara langsung variabel mana yang paling penting untuk setiap komponen, membantu proses pemberian nama/label pada PC.


7 Factor Analysis (FA)

FA berbeda dari PCA karena bertujuan menemukan faktor laten — konstruk yang tidak langsung teramati tetapi menjelaskan pola korelasi antar variabel yang teramati. FA mengasumsikan bahwa setiap variabel dipengaruhi oleh kombinasi faktor bersama (common factors) dan faktor unik (unique factors).

7.1 Parallel Analysis — Menentukan Jumlah Faktor

fa.parallel(X_scaled,
            fa   = "fa",
            fm   = "ml",
            main = "Parallel Analysis untuk Menentukan Jumlah Faktor")

## Parallel analysis suggests that the number of factors =  4  and the number of components =  NA

Penjelasan: Parallel Analysis adalah metode yang lebih akurat dari sekadar menggunakan Kriteria Kaiser (eigenvalue > 1) untuk menentukan jumlah faktor optimal.

Cara kerja Parallel Analysis: 1. R membuat ratusan dataset acak (simulasi) dengan ukuran dan jumlah variabel yang sama dengan data asli. 2. Eigenvalue dari setiap dataset acak dihitung dan dirata-ratakan. 3. Eigenvalue data asli dibandingkan dengan rata-rata eigenvalue data acak. 4. Faktor yang eigenvalue-nya (data asli) melebihi eigenvalue simulasi acak dianggap signifikan dan layak dipertahankan.

Cara membaca grafik: - Garis biru (FA Actual Data): eigenvalue dari data nyata. - Garis merah (Simulated Data): rata-rata eigenvalue dari data acak. - Titik di mana garis biru berada di atas garis merah menentukan jumlah faktor yang direkomendasikan.

Output teks akan menampilkan: “Parallel analysis suggests that the number of factors = 4” → gunakan angka ini sebagai nfactors.

7.2 Ekstraksi Faktor (nfactors = 4)

fa_result <- fa(X_scaled,
                nfactors = 4,        # Sesuai rekomendasi Parallel Analysis
                rotate   = "varimax",
                fm       = "ml")

print(fa_result)
## Factor Analysis using method =  ml
## Call: fa(r = X_scaled, nfactors = 4, rotate = "varimax", fm = "ml")
## Standardized loadings (pattern matrix) based upon correlation matrix
##              ML2   ML1   ML4   ML3   h2    u2 com
## age        -0.02 -0.08 -0.65  0.20 0.47 0.527 1.2
## height_cm   0.70  0.43  0.30  0.10 0.77 0.226 2.1
## weight_kg   0.93  0.00  0.20  0.24 0.96 0.043 1.2
## body_fat   -0.04 -0.97 -0.24  0.03 1.00 0.005 1.1
## diastolic   0.10 -0.02 -0.04  0.75 0.57 0.431 1.0
## systolic    0.15  0.07 -0.07  0.88 0.81 0.194 1.1
## gripForce   0.61  0.45  0.37  0.22 0.77 0.234 2.9
## sit_bend   -0.39  0.03  0.24 -0.01 0.21 0.791 1.7
## sit_ups     0.12  0.43  0.78  0.07 0.82 0.180 1.6
## broad_jump  0.36  0.54  0.61  0.12 0.80 0.205 2.7
## 
##                        ML2  ML1  ML4  ML3
## SS loadings           2.05 1.81 1.80 1.51
## Proportion Var        0.20 0.18 0.18 0.15
## Cumulative Var        0.20 0.39 0.57 0.72
## Proportion Explained  0.29 0.25 0.25 0.21
## Cumulative Proportion 0.29 0.54 0.79 1.00
## 
## Mean item complexity =  1.7
## Test of the hypothesis that 4 factors are sufficient.
## 
## df null model =  45  with the objective function =  6.27 with Chi Square =  83465.15
## df of  the model are 11  and the objective function was  0.17 
## 
## The root mean square of the residuals (RMSR) is  0.02 
## The df corrected root mean square of the residuals is  0.05 
## 
## The harmonic n.obs is  13319 with the empirical chi square  303.85  with prob <  1.4e-58 
## The total n.obs was  13319  with Likelihood Chi Square =  2231.63  with prob <  0 
## 
## Tucker Lewis Index of factoring reliability =  0.891
## RMSEA index =  0.123  and the 90 % confidence intervals are  0.119 0.127
## BIC =  2127.16
## Fit based upon off diagonal values = 1
## Measures of factor score adequacy             
##                                                    ML2  ML1  ML4  ML3
## Correlation of (regression) scores with factors   0.97 0.99 0.90 0.91
## Multiple R square of scores with factors          0.93 0.98 0.81 0.83
## Minimum correlation of possible factor scores     0.86 0.96 0.61 0.67

Penjelasan : print(fa_result) menampilkan hasil lengkap Factor Analysis. Berikut panduan membaca setiap bagian output:

① Standardized loadings (pattern matrix): Tabel utama yang menunjukkan bobot setiap variabel terhadap setiap faktor (ML1–ML4). Loading ≥ 0.40 umumnya dianggap signifikan secara praktis.

② h2 (Communality): Proporsi variansi variabel yang dapat dijelaskan oleh seluruh faktor bersama. Nilai mendekati 1.0 berarti variabel tersebut sangat baik dijelaskan oleh model faktor.

③ u2 (Uniqueness): Variansi unik yang tidak bisa dijelaskan faktor = 1 − h2. Nilai kecil (mendekati 0) lebih baik, artinya variabel tidak memiliki banyak “noise” yang tidak terjelaskan.

④ SS Loadings: Jumlah kuadrat loading per faktor. Menunjukkan total variansi yang dijelaskan oleh faktor tersebut. Nilai > 1 menunjukkan faktor bermakna (Kriteria Kaiser).

⑤ Proportion Var & Cumulative Var: Persentase variansi yang dijelaskan per faktor dan secara kumulatif.

⑥ Indeks Fit Model: - RMSEA: nilai < 0.05 menunjukkan fit sangat baik; < 0.08 masih dapat diterima. - TLI: nilai mendekati 1.0 menunjukkan fit yang baik.

Mengapa nfactors = 4? Karena Parallel Analysis merekomendasikan 4 faktor, dan hasil SS Loadings menunjukkan keempat faktor (ML1–ML4) memiliki nilai > 1, artinya semua faktor bermakna dan tidak ada yang sia-sia.

Mengapa rotasi varimax? Rotasi varimax adalah rotasi ortogonal (faktor-faktor tidak saling berkorelasi) yang memaksimalkan variansi loading dalam setiap faktor. Hasilnya adalah simple structure — setiap variabel memiliki loading tinggi hanya pada satu faktor saja, sehingga interpretasi menjadi lebih mudah dan jelas.

7.3 Tabel Loading Faktor

loadings_fa <- as.data.frame(unclass(fa_result$loadings))
print(round(loadings_fa, 3))
##               ML2    ML1    ML4    ML3
## age        -0.023 -0.080 -0.651  0.203
## height_cm   0.697  0.434  0.298  0.103
## weight_kg   0.926  0.005  0.204  0.240
## body_fat   -0.042 -0.966 -0.241  0.034
## diastolic   0.102 -0.019 -0.039  0.746
## systolic    0.152  0.072 -0.070  0.879
## gripForce   0.613  0.451  0.371  0.221
## sit_bend   -0.385  0.032  0.244 -0.011
## sit_ups     0.123  0.433  0.783  0.066
## broad_jump  0.355  0.536  0.606  0.120

Penjelasan : Tabel loading faktor menampilkan hubungan antara 10 variabel asli dan 4 faktor laten (ML1, ML2, ML3, ML4) setelah rotasi varimax:

  • Setiap kolom = satu faktor laten.
  • Setiap baris = satu variabel.
  • Nilai loading yang ≥ 0.40 (atau ≤ −0.40) menunjukkan variabel tersebut “memuati” faktor itu secara bermakna.

Langkah interpretasi: 1. Untuk setiap faktor, identifikasi variabel dengan loading tertinggi (≥ 0.40). 2. Cari kesamaan tema dari variabel-variabel tersebut. 3. Beri nama faktor berdasarkan tema yang muncul.

Contoh interpretasi umum untuk data kebugaran: - Faktor dengan loading tinggi pada gripForce, broad_jump, sit_ups“Kebugaran Fisik Aktif” - Faktor dengan loading tinggi pada body_fat, weight_kg“Komposisi Tubuh” - Faktor dengan loading tinggi pada systolic, diastolic“Kondisi Kardiovaskular” - Faktor dengan loading tinggi pada age, sit_bend“Kondisi Fisiologis Usia”

7.4 Diagram Struktur Faktor

fa.diagram(fa_result,
           main   = "Diagram Struktur Faktor (4 Faktor)",
           simple = TRUE)

Penjelasan : Diagram path ini menggambarkan hubungan struktural antara faktor laten dan variabel observasi secara visual:

  • Oval/kotak di kiri: faktor-faktor laten (ML1, ML2, ML3, ML4).
  • Teks di kanan: variabel-variabel yang diobservasi.
  • Garis penghubung dengan angka: nilai loading faktor. Hanya loading yang melewati ambang signifikansi yang ditampilkan (karena simple = TRUE).
  • Tanda positif/negatif: arah hubungan antara faktor dan variabel.

7.5 Scree Plot Factor Analysis

eigen_fa <- eigen(cor(X_scaled))$values

plot(eigen_fa, type = "b",
     main = "Scree Plot Factor Analysis",
     xlab = "Faktor ke-",
     ylab = "Eigenvalue",
     pch  = 19,
     col  = "#2E75B6",
     lwd  = 2)
abline(h = 1, col = "red", lty = 2, lwd = 1.5)
legend("topright", legend = "Eigenvalue = 1 (Kriteria Kaiser)",
       col = "red", lty = 2, bty = "n")

Penjelasan : Scree Plot FA menggunakan eigenvalue dari matriks korelasi (bukan matriks kovarian):

  • Titik biru dihubungkan garis: eigenvalue dari setiap faktor potensial, diurutkan dari terbesar ke terkecil.
  • Garis merah putus-putus (y = 1): ambang Kriteria Kaiser. Faktor dengan eigenvalue di atas garis merah dianggap layak dipertahankan.

Cara membaca: 1. Hitung berapa titik biru yang berada di atas garis merah → itulah jumlah faktor berdasarkan Kriteria Kaiser. 2. Perhatikan juga titik “siku” (elbow) sebagai panduan visual tambahan.

Hasil Scree Plot FA ini perlu dikombinasikan dengan hasil Parallel Analysis untuk keputusan final jumlah faktor. Parallel Analysis lebih diutamakan karena lebih akurat, terutama untuk ukuran sampel kecil hingga sedang.

7.6 Heatmap Loading FA

loadings_fa <- as.data.frame(unclass(fa_result$loadings))

load_melt_fa <- melt(as.matrix(loadings_fa))
colnames(load_melt_fa) <- c("Variabel", "Faktor", "Loading")

ggplot(load_melt_fa, aes(x = Faktor, y = Variabel, fill = Loading)) +
  geom_tile(color = "white") +
  geom_text(aes(label = round(Loading, 2)), size = 3.5, fontface = "bold") +
  scale_fill_gradient2(low = "#D73027", mid = "white", high = "#1A6FBA",
                       midpoint = 0, limits = c(-1, 1)) +
  labs(title = "Heatmap Loading Matrix Factor Analysis (4 Faktor)",
       x = "Faktor", y = "Variabel", fill = "Loading") +
  theme_minimal(base_size = 11) +
  theme(plot.title  = element_text(face = "bold"),
        axis.text.y = element_text(size = 10))

Penjelasan : Heatmap loading FA memvisualisasikan struktur faktor secara intuitif — jauh lebih mudah dibaca dibanding tabel angka:

  • Biru tua: loading positif tinggi → variabel sangat berkaitan dengan faktor tersebut (hubungan positif kuat).
  • Merah tua: loading negatif tinggi → variabel berkaitan berlawanan arah dengan faktor.
  • *Putih/pucat**: loading rendah → variabel tidak relevan untuk faktor tersebut.

Tanda keberhasilan rotasi varimax: Heatmap yang “bersih” ditandai dengan pola di mana setiap baris (variabel) hanya memiliki satu sel berwarna gelap (pada satu faktor saja), sementara sel-sel lainnya berwarna putih. Ini menandakan simple structure telah tercapai dan setiap variabel dapat dengan jelas diatribusikan ke satu faktor tertentu.

Dengan heatmap ini, pengelompokan variabel ke dalam 4 faktor menjadi sangat mudah dibaca secara visual, dan proses penamaan/interpretasi faktor menjadi lebih mudah dilakukan.


8 Perbandingan PCA dan FA

Aspek PCA FA
Tujuan utama Reduksi dimensi, memaksimalkan variansi Menemukan faktor laten yang tidak teramati
Asumsi model Tidak ada model probabilistik Ada model probabilistik (faktor + error unik)
Komunalitas (h²) Diasumsikan = 1 untuk semua variabel Diestimasi dari data, bisa < 1
Jumlah komponen Sama dengan variabel (dipilih sebagian) Lebih sedikit dari jumlah variabel
Rotasi Opsional Umumnya digunakan (varimax, oblimin)
Interpretasi PC = kombinasi linier variabel Faktor = konstruk laten bermakna
Penggunaan Preprocessing, reduksi noise, visualisasi Validasi konstruk, pembuatan indeks/skala
Penentuan jumlah Scree plot, % variansi kumulatif Parallel Analysis, Kriteria Kaiser

9 Kesimpulan

  1. Uji Asumsi: Data memenuhi syarat untuk PCA dan FA (KMO ≥ 0.70, Bartlett p < 0.05).

  2. PCA: Beberapa PC pertama mampu menjelaskan sebagian besar variansi data (~80%). PC1 umumnya menangkap dimensi kebugaran aktif, PC2 menangkap dimensi komposisi/ukuran tubuh.

  3. FA: 4 faktor laten berhasil diidentifikasi, merepresentasikan konstruk-konstruk seperti kebugaran fisik aktif, komposisi tubuh, dan kondisi kardiovaskular. Rotasi varimax menghasilkan struktur faktor yang mudah diinterpretasikan.

  4. Implikasi praktis: Variabel kebugaran yang berjumlah 10 dapat dirangkum menjadi 4 dimensi/faktor utama tanpa kehilangan informasi yang signifikan, memudahkan analisis lanjutan atau pembuatan indeks kebugaran.