Bagian ini memuat ekstraksi factor scores, statistik deskriptif, matriks korelasi, serta visualisasi distribusi dan density factor scores.

5.1 Ekstraksi Factor Scores

Kode
Fscores_peb <- lavPredict(fit_peb, type = "lv")
Fscores_ol  <- lavPredict(fit_ol,  type = "lv")
Fscores_ccs <- lavPredict(fit_ccs, type = "lv")

data_Fscores <- data.frame(
    PEB = Fscores_peb[, "PEB"],
    OL  = Fscores_ol[,  "OL"],
    CCS = Fscores_ccs[, "GCCS"]
)
cat("Factor scores berhasil diekstraksi:", nrow(data_Fscores), "observasi x 3 variabel")
Factor scores berhasil diekstraksi: 538 observasi x 3 variabel

5.2 Statistik Deskriptif Factor Scores

Kode
var_desc <- psych::describe(data_Fscores, type = 2)
knitr::kable(data.frame(
    Variabel = rownames(var_desc), N = var_desc$n,
    Mean = round(var_desc$mean, 3), SD = round(var_desc$sd, 3),
    Min = round(var_desc$min, 3), Max = round(var_desc$max, 3),
    Skewness = round(var_desc$skew, 3), Kurtosis = round(var_desc$kurtosis, 3),
    check.names = FALSE
), caption = "Statistik Deskriptif Factor Scores", row.names = FALSE)
Statistik Deskriptif Factor Scores
Variabel N Mean SD Min Max Skewness Kurtosis
PEB 538 0 0.953 -3.063 2.106 0.305 -0.109
OL 538 0 0.959 -4.329 1.658 -0.166 0.067
CCS 538 0 0.949 -1.365 3.067 0.655 -0.241

5.3 Distribusi Factor Scores — Histogram & Density

Kode distribusi histogram + density
# ---- Hitung cutoff per variabel ----
peb_low <- mean(data_Fscores$PEB, na.rm = TRUE) - 0.5 * sd(data_Fscores$PEB, na.rm = TRUE)
peb_hi <- mean(data_Fscores$PEB, na.rm = TRUE) + 0.5 * sd(data_Fscores$PEB, na.rm = TRUE)
ccs_low <- mean(data_Fscores$CCS, na.rm = TRUE) - 0.5 * sd(data_Fscores$CCS, na.rm = TRUE)
ccs_hi <- mean(data_Fscores$CCS, na.rm = TRUE) + 0.5 * sd(data_Fscores$CCS, na.rm = TRUE)
ol_low <- mean(data_Fscores$OL, na.rm = TRUE) - 0.5 * sd(data_Fscores$OL, na.rm = TRUE)
ol_hi <- mean(data_Fscores$OL, na.rm = TRUE) + 0.5 * sd(data_Fscores$OL, na.rm = TRUE)

# Kategorisasi untuk warna histogram
breaks_peb <- hist(data_Fscores$PEB, plot = FALSE, breaks = 20)
colors_peb <- cut(breaks_peb$mids, breaks = c(-Inf, peb_low, peb_hi, Inf), labels = c("lightsteelblue", "steelblue", "darkslategray"))
breaks_ccs <- hist(data_Fscores$CCS, plot = FALSE, breaks = 20)
colors_ccs <- cut(breaks_ccs$mids, breaks = c(-Inf, ccs_low, ccs_hi, Inf), labels = c("lightsalmon", "coral", "darkred"))
breaks_ol <- hist(data_Fscores$OL, plot = FALSE, breaks = 20)
colors_ol <- cut(breaks_ol$mids, breaks = c(-Inf, ol_low, ol_hi, Inf), labels = c("palegreen", "lightgreen", "darkgreen"))

# Jumlah per kategori
categorize_score <- function(scores, labels = c("Rendah", "Sedang", "Tinggi")) {
    m <- mean(scores, na.rm = TRUE); s <- sd(scores, na.rm = TRUE)
    ifelse(scores < m - 0.5*s, labels[1], ifelse(scores > m + 0.5*s, labels[3], labels[2]))
}
data_Fscores$PEB_cat <- categorize_score(data_Fscores$PEB)
data_Fscores$CCS_cat <- categorize_score(data_Fscores$CCS)
data_Fscores$OL_cat <- categorize_score(data_Fscores$OL)
peb_n <- table(data_Fscores$PEB_cat)
ccs_n <- table(data_Fscores$CCS_cat)
ol_n <- table(data_Fscores$OL_cat)

par(mfrow = c(2, 3), mar = c(7, 4, 4, 2) + 0.5)

# --- Histogram 1: PEB ---
hist(data_Fscores$PEB, main = "Distribusi PEB", xlab = "Skor", col = as.character(colors_peb), border = "white", xlim = c(-4, 3), ylim = c(0, 150), breaks = 20)
op <- par(family = "mono")
legend("bottom", inset = c(0, -0.42),
    legend = c(
        sprintf("%-6s (n=%3d) [%6.2f, %5.2f]", "Rendah", peb_n["Rendah"], min(data_Fscores$PEB, na.rm = TRUE), peb_low),
        sprintf("%-6s (n=%3d) [%6.2f, %5.2f]", "Sedang", peb_n["Sedang"], peb_low, peb_hi),
        sprintf("%-6s (n=%3d) [%6.2f, %5.2f]", "Tinggi", peb_n["Tinggi"], peb_hi, max(data_Fscores$PEB, na.rm = TRUE))
    ), fill = c("lightsteelblue", "steelblue", "darkslategray"), cex = 0.85, bty = "n", xpd = TRUE)
par(op)

# --- Histogram 2: CCS ---
hist(data_Fscores$CCS, main = "Distribusi CCS", xlab = "Skor", col = as.character(colors_ccs), border = "white", xlim = c(-4, 3), ylim = c(0, 150), breaks = 20)
op <- par(family = "mono")
legend("bottom", inset = c(0, -0.42),
    legend = c(
        sprintf("%-6s (n=%3d) [%6.2f, %5.2f]", "Rendah", ccs_n["Rendah"], min(data_Fscores$CCS, na.rm = TRUE), ccs_low),
        sprintf("%-6s (n=%3d) [%6.2f, %5.2f]", "Sedang", ccs_n["Sedang"], ccs_low, ccs_hi),
        sprintf("%-6s (n=%3d) [%6.2f, %5.2f]", "Tinggi", ccs_n["Tinggi"], ccs_hi, max(data_Fscores$CCS, na.rm = TRUE))
    ), fill = c("lightsalmon", "coral", "darkred"), cex = 0.85, bty = "n", xpd = TRUE)
par(op)

# --- Histogram 3: OL ---
hist(data_Fscores$OL, main = "Distribusi OL", xlab = "Skor", col = as.character(colors_ol), border = "white", xlim = c(-4, 3), ylim = c(0, 150), breaks = 20)
op <- par(family = "mono")
legend("bottom", inset = c(0, -0.42),
    legend = c(
        sprintf("%-6s (n=%3d) [%6.2f, %5.2f]", "Rendah", ol_n["Rendah"], min(data_Fscores$OL, na.rm = TRUE), ol_low),
        sprintf("%-6s (n=%3d) [%6.2f, %5.2f]", "Sedang", ol_n["Sedang"], ol_low, ol_hi),
        sprintf("%-6s (n=%3d) [%6.2f, %5.2f]", "Tinggi", ol_n["Tinggi"], ol_hi, max(data_Fscores$OL, na.rm = TRUE))
    ), fill = c("palegreen", "lightgreen", "darkgreen"), cex = 0.85, bty = "n", xpd = TRUE)
par(op)

# --- Density Plot 1: PEB ---
plot(density(data_Fscores$PEB, na.rm = TRUE), main = "Density PEB", xlab = "Skor", xlim = c(-4, 3), ylim = c(0, 1.2), lwd = 2, col = "steelblue")
abline(v = peb_low, col = "steelblue", lty = 2, lwd = 1.2)
abline(v = peb_hi, col = "darkslategray", lty = 2, lwd = 1.2)
op <- par(family = "mono")
legend("bottom", inset = c(0, -0.38),
    legend = c(
        sprintf("Rendah (n=%3d): x < %5.2f", peb_n["Rendah"], peb_low),
        sprintf("Sedang (n=%3d): %5.2f s.d. %5.2f", peb_n["Sedang"], peb_low, peb_hi),
        sprintf("Tinggi (n=%3d): x > %5.2f", peb_n["Tinggi"], peb_hi)
    ), fill = c("lightsteelblue", "steelblue", "darkslategray"), cex = 0.85, bty = "n", xpd = TRUE)
par(op)

# --- Density Plot 2: CCS ---
plot(density(data_Fscores$CCS, na.rm = TRUE), main = "Density CCS", xlab = "Skor", xlim = c(-4, 3), ylim = c(0, 1.2), lwd = 2, col = "coral")
abline(v = ccs_low, col = "coral", lty = 2, lwd = 1.2)
abline(v = ccs_hi, col = "darkred", lty = 2, lwd = 1.2)
op <- par(family = "mono")
legend("bottom", inset = c(0, -0.38),
    legend = c(
        sprintf("Rendah (n=%3d): x < %5.2f", ccs_n["Rendah"], ccs_low),
        sprintf("Sedang (n=%3d): %5.2f s.d. %5.2f", ccs_n["Sedang"], ccs_low, ccs_hi),
        sprintf("Tinggi (n=%3d): x > %5.2f", ccs_n["Tinggi"], ccs_hi)
    ), fill = c("lightsalmon", "coral", "darkred"), cex = 0.85, bty = "n", xpd = TRUE)
par(op)

# --- Density Plot 3: OL ---
plot(density(data_Fscores$OL, na.rm = TRUE), main = "Density OL", xlab = "Skor", xlim = c(-4, 3), ylim = c(0, 1.2), lwd = 2, col = "lightgreen")
abline(v = ol_low, col = "lightgreen", lty = 2, lwd = 1.2)
abline(v = ol_hi, col = "darkgreen", lty = 2, lwd = 1.2)
op <- par(family = "mono")
legend("bottom", inset = c(0, -0.38),
    legend = c(
        sprintf("Rendah (n=%3d): x < %5.2f", ol_n["Rendah"], ol_low),
        sprintf("Sedang (n=%3d): %5.2f s.d. %5.2f", ol_n["Sedang"], ol_low, ol_hi),
        sprintf("Tinggi (n=%3d): x > %5.2f", ol_n["Tinggi"], ol_hi)
    ), fill = c("palegreen", "lightgreen", "darkgreen"), cex = 0.85, bty = "n", xpd = TRUE)

Kode distribusi histogram + density
par(op)

par(mfrow = c(1, 1), mar = c(5, 4, 4, 2) + 0.1)

5.3.1 Frekuensi Kategori

Kode
for (v in c("PEB", "CCS", "OL")) {
    scores <- data_Fscores[[v]]
    cats <- categorize_score(scores)
    freq <- table(cats)
    pct <- round(prop.table(freq) * 100, 1)
    cat(sprintf("\n%s: Rendah=%d (%.1f%%), Sedang=%d (%.1f%%), Tinggi=%d (%.1f%%)\n",
        v, freq["Rendah"], pct["Rendah"], freq["Sedang"], pct["Sedang"], freq["Tinggi"], pct["Tinggi"]))
}

PEB: Rendah=189 (35.1%), Sedang=189 (35.1%), Tinggi=160 (29.7%)

CCS: Rendah=202 (37.5%), Sedang=177 (32.9%), Tinggi=159 (29.6%)

OL: Rendah=157 (29.2%), Sedang=235 (43.7%), Tinggi=146 (27.1%)

5.4 Matriks Korelasi Pearson

Kode
cor_matrix   <- cor(data_Fscores[, c("PEB", "OL", "CCS")], use = "complete.obs")
corr_pvalues <- corr.test(data_Fscores[, c("PEB", "OL", "CCS")], use = "complete.obs")
Kode
knitr::kable(round(cor_matrix, 3), caption = "Matriks Korelasi Pearson")
Matriks Korelasi Pearson
PEB OL CCS
PEB 1.000 0.391 0.128
OL 0.391 1.000 -0.226
CCS 0.128 -0.226 1.000

5.4.1 Korelasi dengan Notasi Signifikansi

Kode
add_significance <- function(cor_val, p_val) {
    if (is.na(p_val)) return(sprintf("%.3f", cor_val))
    if (p_val < 0.001) return(sprintf("%.3f***", cor_val))
    if (p_val < 0.01)  return(sprintf("%.3f**", cor_val))
    if (p_val < 0.05)  return(sprintf("%.3f*", cor_val))
    sprintf("%.3f", cor_val)
}
cor_sig <- matrix(mapply(add_significance, as.vector(cor_matrix), as.vector(corr_pvalues$p)),
                   nrow = 3, dimnames = list(c("PEB", "OL", "CCS"), c("PEB", "OL", "CCS")))
knitr::kable(cor_sig, caption = "Korelasi dengan Notasi Signifikansi")
Korelasi dengan Notasi Signifikansi
PEB OL CCS
PEB 1.000*** 0.391*** 0.128**
OL 0.391*** 1.000*** -0.226***
CCS 0.128** -0.226*** 1.000***

5.4.2 Visualisasi Matriks Korelasi

Kode matriks korelasi
# ---- Hitung korelasi & p-value ----
cor_vars <- c("PEB", "OL", "CCS")
cor_data_utama <- data_Fscores[, cor_vars]
cor_res <- psych::corr.test(cor_data_utama, use = "complete.obs")
cor_r <- round(cor_res$r, 2)
cor_p <- cor_res$p

# ---- Fungsi: nilai r + bintang signifikansi ----
add_significance <- function(cor_val, p_val) {
    stars <- ifelse(p_val < .001, "***", ifelse(p_val < .01, "**",
        ifelse(p_val < .05, "*", "")
    ))
    paste0(sprintf("%.2f", cor_val), stars)
}

cor_sig_matrix <- matrix(
    mapply(add_significance, as.vector(cor_r), as.vector(cor_p)),
    nrow = length(cor_vars), ncol = length(cor_vars),
    dimnames = list(cor_vars, cor_vars)
)

# ---- Long-format grid ----
cor_long <- expand.grid(
    row = factor(cor_vars, levels = rev(cor_vars)),
    col = factor(cor_vars, levels = cor_vars),
    stringsAsFactors = FALSE
)
cor_long$r <- mapply(
    function(r, c) cor_r[as.character(r), as.character(c)],
    cor_long$row, cor_long$col
)
cor_long$sig <- mapply(
    function(r, c) cor_sig_matrix[as.character(r), as.character(c)],
    cor_long$row, cor_long$col
)
cor_long$row_i <- match(as.character(cor_long$row), cor_vars)
cor_long$col_i <- match(as.character(cor_long$col), cor_vars)
cor_long$panel <- ifelse(cor_long$row_i == cor_long$col_i, "diag",
    ifelse(cor_long$row_i < cor_long$col_i, "upper", "lower")
)

cor_tile <- cor_long[cor_long$panel == "upper", ]
cor_diag <- cor_long[cor_long$panel == "diag", ]

# ---- Plot ----
p_corr <- ggplot(cor_long, aes(x = col, y = row)) +
    # Grid putih untuk semua sel (border tipis)
    geom_tile(fill = "white", color = "grey80", linewidth = 0.5) +
    # Upper triangle — warna berdasarkan r
    geom_tile(data = cor_tile, aes(fill = r), color = "white", linewidth = 0.5) +
    # Nilai r + bintang (teks putih di atas tile)
    geom_text(
        data = cor_tile, aes(label = sig),
        size = 5, fontface = "bold", color = "white"
    ) +
    # Nama variabel di diagonal
    geom_text(
        data = cor_diag, aes(label = as.character(col)),
        size = 5.5, fontface = "bold", color = "grey20"
    ) +
    scale_fill_gradient2(
        low = "#2166AC",
        mid = "white",
        high = "#B2182B",
        midpoint = 0,
        limits = c(-1, 1),
        name = "Pearson r",
        guide = guide_colorbar(
            barwidth = 1.2, barheight = 8,
            title.position = "top", title.hjust = 0.5
        )
    ) +
    scale_x_discrete(position = "top") +
    labs(
        title = "Pearson Correlation Matrix",
        subtitle = paste0(
            "Variabel utama: PEB, OL, CCS (standardized factor scores; N = ",
            nrow(cor_data_utama), ")"
        ),
        caption = "*** p < .001   ** p < .01   * p < .05 (two-tailed, adjusted for multiple comparisons)"
    ) +
    theme_bw(base_size = 12) +
    theme(
        plot.title = element_text(face = "bold", size = 13, hjust = 0.5),
        plot.subtitle = element_text(
            size = 9.5, hjust = 0.5, color = "grey35",
            margin = margin(b = 8)
        ),
        plot.caption = element_text(
            size = 8, color = "grey50", hjust = 0,
            margin = margin(t = 8)
        ),
        axis.text.x = element_text(size = 11, face = "bold"),
        axis.text.y = element_text(size = 11, face = "bold"),
        axis.title = element_blank(),
        axis.ticks = element_blank(),
        panel.border = element_rect(color = "grey70"),
        panel.grid = element_blank(),
        legend.title = element_text(face = "bold", size = 9),
        legend.text = element_text(size = 8.5),
        plot.margin = margin(15, 15, 10, 15)
    )

print(p_corr)

TipPanduan Interpretasi
  • Notasi: *** p<.001 | ** p<.01 | * p<.05
  • Kekuatan (Cohen, 1992): |r|<0.30 = Kecil | 0.30–0.49 = Sedang | ≥0.50 = Besar