Dalam konteks pendidikan tinggi, pemahaman tentang hubungan antara jenis program studi dan tingkat kepuasan mahasiswa sangat penting untuk perbaikan kualitas pembelajaran. Analisis ini dilakukan untuk mengidentifikasi pola hubungan antara dua variabel kategorik tersebut menggunakan Analisis Korespondensi, yang memungkinkan visualisasi dan interpretasi hubungan dalam ruang dimensi tereduksi. Data yang digunakan berupa tabel kontingensi 4×4 dengan total 235 responden, mewakili empat jenis program studi (Sains, Teknik, Sosial, Humaniora) dan empat tingkat kepuasan (Sangat Puas, Puas, Cukup, Tidak Puas). Hasil analisis diharapkan dapat memberikan wawasan bagi peningkatan kualitas pendidikan di perguruan tinggi.

suppressPackageStartupMessages({
  if(!require(FactoMineR, quietly = TRUE)) {
    install.packages("FactoMineR", quiet = TRUE)
  }
  if(!require(factoextra, quietly = TRUE)) {
    install.packages("factoextra", quiet = TRUE)
  }
  if(!require(ggplot2, quietly = TRUE)) {
    install.packages("ggplot2", quiet = TRUE)
  }
  if(!require(gplots, quietly = TRUE)) {
    install.packages("gplots", quiet = TRUE)
  }
  
  library(FactoMineR)
  library(factoextra)
  library(ggplot2)
  library(gplots)
})

set.seed(123)

1 Data

data_matrix <- matrix(c(
  25, 15, 8, 5,   # Sains
  30, 25, 12, 8,  # Teknik
  15, 20, 18, 12, # Sosial
  10, 12, 15, 20  # Humaniora
), nrow = 4, byrow = TRUE)

# Menamai baris dan kolom
rownames(data_matrix) <- c("Sains", "Teknik", "Sosial", "Humaniora")
colnames(data_matrix) <- c("Sangat Puas", "Puas", "Cukup", "Tidak Puas")

# Konversi ke data frame untuk analisis
data_df <- as.data.frame(data_matrix)

cat("TABEL KONTINGENSI\n")
## TABEL KONTINGENSI
print(data_df)
##           Sangat Puas Puas Cukup Tidak Puas
## Sains              25   15     8          5
## Teknik             30   25    12          8
## Sosial             15   20    18         12
## Humaniora          10   12    15         20

2 Uji Chi-Square

cat("UJI CHI-SQUARE UNTUK TABEL KONTINGENSI\n")
## UJI CHI-SQUARE UNTUK TABEL KONTINGENSI
# Melakukan uji Chi-Square
chi_test <- chisq.test(data_matrix)

# Menampilkan hasil uji Chi-Square
print(chi_test)
## 
##  Pearson's Chi-squared test
## 
## data:  data_matrix
## X-squared = 30.006, df = 9, p-value = 0.0004376
cat("HASIL UJI CHI-SQUARE\n")
## HASIL UJI CHI-SQUARE
cat("Statistik Chi-Square:", round(chi_test$statistic, 3), "\n")
## Statistik Chi-Square: 30.006
cat("Derajat Kebebasan:", chi_test$parameter, "\n")
## Derajat Kebebasan: 9
cat("p-value:", format.pval(chi_test$p.value), "\n")
## p-value: 0.00043764
if(chi_test$p.value < 0.05) {
  cat("Kesimpulan: Terdapat hubungan signifikan antar variabel (p < 0.05)\n")
} else {
  cat("Kesimpulan: Tidak terdapat hubungan signifikan antar variabel (p ≥ 0.05)\n")
}
## Kesimpulan: Terdapat hubungan signifikan antar variabel (p < 0.05)

3 Analisis Korespondensi

cat("ANALISIS KORESPONDENSI (CA)\n")
## ANALISIS KORESPONDENSI (CA)
# Melakukan Analisis Korespondensi
ca_result <- CA(data_matrix, graph = FALSE)

# Menampilkan ringkasan hasil CA
print(summary(ca_result))
## 
## Call:
## CA(X = data_matrix, graph = FALSE) 
## 
## The chi square of independence between the two variables is equal to 30.00629 (p-value =  0.0004376412 ).
## 
## Eigenvalues
##                        Dim.1   Dim.2   Dim.3
## Variance               0.108   0.011   0.001
## % of var.             89.912   9.091   0.997
## Cumulative % of var.  89.912  99.003 100.000
## 
## Rows
##               Iner*1000    Dim.1    ctr   cos2    Dim.2    ctr   cos2    Dim.3
## Sains       |    27.634 | -0.346 23.487  0.917 |  0.093 16.737  0.066 |  0.047
## Teknik      |    20.930 | -0.260 18.808  0.970 | -0.009  0.213  0.001 | -0.045
## Sosial      |    12.019 |  0.144  5.001  0.449 | -0.158 59.677  0.542 |  0.021
## Humaniora   |    59.442 |  0.499 52.705  0.957 |  0.106 23.372  0.043 | -0.008
##                ctr   cos2  
## Sains       38.577  0.017 |
## Teknik      50.979  0.029 |
## Sosial       9.322  0.009 |
## Humaniora    1.122  0.000 |
## 
## Columns
##               Iner*1000    Dim.1    ctr   cos2    Dim.2    ctr   cos2    Dim.3
## Sangat Puas |    42.605 | -0.354 37.067  0.939 |  0.089 22.983  0.059 |  0.017
## Puas        |     7.261 | -0.119  3.778  0.562 | -0.096 24.465  0.368 | -0.042
## Cukup       |    15.538 |  0.241 11.419  0.793 | -0.113 24.796  0.174 |  0.049
## Tidak Puas  |    54.621 |  0.535 47.736  0.943 |  0.130 27.757  0.055 | -0.021
##                ctr   cos2  
## Sangat Puas  7.950  0.002 |
## Puas        42.957  0.071 |
## Cukup       42.585  0.033 |
## Tidak Puas   6.508  0.001 |
## NULL
plot(ca_result, 
     title = "Biplot Analisis Korespondensi - Program Studi vs Kepuasan",
     cex = 1.2)

# Kontribusi baris
fviz_ca_row(ca_result, 
            col.row = "contrib",
            gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
            repel = TRUE,
            title = "Posisi Baris (Program Studi) dengan Kontribusi")

# Kontribusi kolom
fviz_ca_col(ca_result,
            col.col = "contrib",
            gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
            repel = TRUE,
            title = "Posisi Kolom (Tingkat Kepuasan) dengan Kontribusi")

heatmap_data <- as.matrix(data_matrix)
heatmap.2(heatmap_data,
          main = "Heatmap Tabel Kontingensi",
          xlab = "Tingkat Kepuasan",
          ylab = "Program Studi",
          col = colorRampPalette(c("white", "steelblue"))(256),
          scale = "none",
          margins = c(8, 8),
          cexRow = 1.2,
          cexCol = 1.2,
          trace = "none",
          density.info = "none",
          key = TRUE,
          keysize = 1.5)

cat("METRIK PENTING ANALISIS KORESPONDENSI\n")
## METRIK PENTING ANALISIS KORESPONDENSI
# Eigenvalues dan variansi yang dijelaskan
cat("\n1. EIGENVALUES DAN VARIANSI YANG DIJELASKAN:\n")
## 
## 1. EIGENVALUES DAN VARIANSI YANG DIJELASKAN:
eigen_df <- as.data.frame(ca_result$eig)
colnames(eigen_df) <- c("Eigenvalue", "Persentase Variansi", "Persentase Kumulatif")
print(round(eigen_df, 4))
##       Eigenvalue Persentase Variansi Persentase Kumulatif
## dim 1     0.1079             89.9123              89.9123
## dim 2     0.0109              9.0906              99.0029
## dim 3     0.0012              0.9971             100.0000
# Koordinat baris
cat("\n2. KOORDINAT BARIS (PROGRAM STUDI):\n")
## 
## 2. KOORDINAT BARIS (PROGRAM STUDI):
row_coord <- as.data.frame(ca_result$row$coord)
colnames(row_coord) <- paste("Dim", 1:ncol(row_coord), sep = " ")
print(round(row_coord, 4))
##             Dim 1   Dim 2   Dim 3
## Sains     -0.3458  0.0928  0.0467
## Teknik    -0.2601 -0.0088 -0.0451
## Sosial     0.1441 -0.1583  0.0207
## Humaniora  0.4995  0.1058 -0.0077
# Koordinat kolom
cat("\n3. KOORDINAT KOLOM (TINGKAT KEPUASAN):\n")
## 
## 3. KOORDINAT KOLOM (TINGKAT KEPUASAN):
col_coord <- as.data.frame(ca_result$col$coord)
colnames(col_coord) <- paste("Dim", 1:ncol(col_coord), sep = " ")
print(round(col_coord, 4))
##               Dim 1   Dim 2   Dim 3
## Sangat Puas -0.3536  0.0885  0.0172
## Puas        -0.1190 -0.0963 -0.0422
## Cukup        0.2411 -0.1130  0.0490
## Tidak Puas   0.5350  0.1297 -0.0208
# Kontribusi baris
cat("\n4. KONTRIBUSI BARIS (%):\n")
## 
## 4. KONTRIBUSI BARIS (%):
row_contrib <- as.data.frame(ca_result$row$contrib)
colnames(row_contrib) <- paste("Dim", 1:ncol(row_contrib), sep = " ")
print(round(row_contrib, 2))
##           Dim 1 Dim 2 Dim 3
## Sains     23.49 16.74 38.58
## Teknik    18.81  0.21 50.98
## Sosial     5.00 59.68  9.32
## Humaniora 52.71 23.37  1.12
# Kontribusi kolom
cat("\n5. KONTRIBUSI KOLOM (%):\n")
## 
## 5. KONTRIBUSI KOLOM (%):
col_contrib <- as.data.frame(ca_result$col$contrib)
colnames(col_contrib) <- paste("Dim", 1:ncol(col_contrib), sep = " ")
print(round(col_contrib, 2))
##             Dim 1 Dim 2 Dim 3
## Sangat Puas 37.07 22.98  7.95
## Puas         3.78 24.46 42.96
## Cukup       11.42 24.80 42.59
## Tidak Puas  47.74 27.76  6.51
# Cos2 (kualitas representasi)
cat("\n6. KUALITAS REPRESENTASI (COS2) BARIS:\n")
## 
## 6. KUALITAS REPRESENTASI (COS2) BARIS:
row_cos2 <- as.data.frame(ca_result$row$cos2)
colnames(row_cos2) <- paste("Dim", 1:ncol(row_cos2), sep = " ")
print(round(row_cos2, 4))
##            Dim 1  Dim 2  Dim 3
## Sains     0.9172 0.0661 0.0167
## Teknik    0.9697 0.0011 0.0291
## Sosial    0.4490 0.5417 0.0093
## Humaniora 0.9569 0.0429 0.0002
cat("\n7. KUALITAS REPRESENTASI (COS2) KOLOM:\n")
## 
## 7. KUALITAS REPRESENTASI (COS2) KOLOM:
col_cos2 <- as.data.frame(ca_result$col$cos2)
colnames(col_cos2) <- paste("Dim", 1:ncol(col_cos2), sep = " ")
print(round(col_cos2, 4))
##              Dim 1  Dim 2  Dim 3
## Sangat Puas 0.9389 0.0589 0.0022
## Puas        0.5616 0.3676 0.0708
## Cukup       0.7931 0.1741 0.0328
## Tidak Puas  0.9431 0.0554 0.0014

4 Interpretasi Hasil

cat("INTERPRETASI AWAL\n")
## INTERPRETASI AWAL
# Interpretasi berdasarkan eigenvalues
total_variance <- sum(ca_result$eig[,1])
dim1_variance <- ca_result$eig[1,2]
dim2_variance <- ca_result$eig[2,2]
cumulative_variance <- dim1_variance + dim2_variance

cat("\n1. KUALITAS REPRESENTASI DIMENSI:\n")
## 
## 1. KUALITAS REPRESENTASI DIMENSI:
cat("   - Dimensi 1 menjelaskan", round(dim1_variance, 1), "% variansi\n")
##    - Dimensi 1 menjelaskan 89.9 % variansi
cat("   - Dimensi 2 menjelaskan", round(dim2_variance, 1), "% variansi\n")
##    - Dimensi 2 menjelaskan 9.1 % variansi
cat("   - Dua dimensi pertama menjelaskan", round(cumulative_variance, 1), 
    "% variansi total\n")
##    - Dua dimensi pertama menjelaskan 99 % variansi total
if(cumulative_variance >= 70) {
  cat("   → Dua dimensi pertama sudah merepresentasikan data dengan baik\n")
} else {
  cat("   → Pertimbangkan untuk melihat dimensi tambahan\n")
}
##    → Dua dimensi pertama sudah merepresentasikan data dengan baik
# Identifikasi asosiasi terkuat
cat("\n2. ASOSIASI TERKUAT (berdasarkan kedekatan dalam biplot):\n")
## 
## 2. ASOSIASI TERKUAT (berdasarkan kedekatan dalam biplot):
# Mencari asosiasi terdekat antara baris dan kolom
for(i in 1:nrow(row_coord)) {
  distances <- sqrt(rowSums((sweep(col_coord, 2, as.numeric(row_coord[i,])))^2))
  closest <- which.min(distances)
  cat("   -", rownames(row_coord)[i], "paling terkait dengan", 
      rownames(col_coord)[closest], "\n")
}
##    - Sains paling terkait dengan Sangat Puas 
##    - Teknik paling terkait dengan Sangat Puas 
##    - Sosial paling terkait dengan Cukup 
##    - Humaniora paling terkait dengan Tidak Puas