# LOAD LIBRARY
library(lavaan)
## Warning: package 'lavaan' was built under R version 4.5.3
## This is lavaan 0.6-21
## lavaan is FREE software! Please report any bugs.
library(psych)
## Warning: package 'psych' was built under R version 4.5.3
##
## Attaching package: 'psych'
## The following object is masked from 'package:lavaan':
##
## cor2cov
library(corrplot)
## Warning: package 'corrplot' was built under R version 4.5.3
## corrplot 0.95 loaded
library(semPlot)
## Warning: package 'semPlot' was built under R version 4.5.3
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.5.3
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.5.3
##
## Attaching package: 'ggplot2'
## The following objects are masked from 'package:psych':
##
## %+%, alpha
library(car)
## Warning: package 'car' was built under R version 4.5.3
## Loading required package: carData
## Warning: package 'carData' was built under R version 4.5.3
## Registered S3 method overwritten by 'car':
## method from
## na.action.merMod lme4
##
## Attaching package: 'car'
## The following object is masked from 'package:dplyr':
##
## recode
## The following object is masked from 'package:psych':
##
## logit
# LOAD DATA
data <- read.csv("C:\\Users\\zahir\\Downloads\\StressLevelDataset.csv")
str(data)
## 'data.frame': 1100 obs. of 21 variables:
## $ anxiety_level : int 14 15 12 16 16 20 4 17 13 6 ...
## $ self_esteem : int 20 8 18 12 28 13 26 3 22 8 ...
## $ mental_health_history : int 0 1 1 1 0 1 0 1 1 0 ...
## $ depression : int 11 15 14 15 7 21 6 22 12 27 ...
## $ headache : int 2 5 2 4 2 3 1 4 3 4 ...
## $ blood_pressure : int 1 3 1 3 3 3 2 3 1 3 ...
## $ sleep_quality : int 2 1 2 1 5 1 4 1 2 1 ...
## $ breathing_problem : int 4 4 2 3 1 4 1 5 4 2 ...
## $ noise_level : int 2 3 2 4 3 3 1 3 3 0 ...
## $ living_conditions : int 3 1 2 2 2 2 4 1 3 5 ...
## $ safety : int 3 2 3 2 4 2 4 1 3 2 ...
## $ basic_needs : int 2 2 2 2 3 1 4 1 3 2 ...
## $ academic_performance : int 3 1 2 2 4 2 5 1 3 2 ...
## $ study_load : int 2 4 3 4 3 5 1 3 3 2 ...
## $ teacher_student_relationship: int 3 1 3 1 1 2 4 2 2 1 ...
## $ future_career_concerns : int 3 5 2 4 2 5 1 4 3 5 ...
## $ social_support : int 2 1 2 1 1 1 3 1 3 1 ...
## $ peer_pressure : int 3 4 3 4 5 4 2 4 3 5 ...
## $ extracurricular_activities : int 3 5 2 4 0 4 2 4 2 3 ...
## $ bullying : int 2 5 2 5 5 5 1 5 2 4 ...
## $ stress_level : int 1 2 1 2 1 2 0 2 1 1 ...
head(data)
## anxiety_level self_esteem mental_health_history depression headache
## 1 14 20 0 11 2
## 2 15 8 1 15 5
## 3 12 18 1 14 2
## 4 16 12 1 15 4
## 5 16 28 0 7 2
## 6 20 13 1 21 3
## blood_pressure sleep_quality breathing_problem noise_level living_conditions
## 1 1 2 4 2 3
## 2 3 1 4 3 1
## 3 1 2 2 2 2
## 4 3 1 3 4 2
## 5 3 5 1 3 2
## 6 3 1 4 3 2
## safety basic_needs academic_performance study_load
## 1 3 2 3 2
## 2 2 2 1 4
## 3 3 2 2 3
## 4 2 2 2 4
## 5 4 3 4 3
## 6 2 1 2 5
## teacher_student_relationship future_career_concerns social_support
## 1 3 3 2
## 2 1 5 1
## 3 3 2 2
## 4 1 4 1
## 5 1 2 1
## 6 2 5 1
## peer_pressure extracurricular_activities bullying stress_level
## 1 3 3 2 1
## 2 4 5 5 2
## 3 3 2 2 1
## 4 4 4 5 2
## 5 5 0 5 1
## 6 4 4 5 2
# CEK KUALITAS DATA
cat(" CEK KUALITAS DATA\n")
## CEK KUALITAS DATA
cat("Dimensi data :", dim(data), "\n")
## Dimensi data : 1100 21
cat("Missing values :", sum(is.na(data)), "\n")
## Missing values : 0
cat("Duplikat :", sum(duplicated(data)), "\n")
## Duplikat : 0
data <- na.omit(data)
cat("Dimensi setelah na.omit:", dim(data), "\n")
## Dimensi setelah na.omit: 1100 21
# SELEKSI & REVERSE CODING
# Reverse coding untuk indikator yang loading-nya negatif
sem_data <- data %>%
select(
anxiety_level, self_esteem, mental_health_history, depression,
headache, sleep_quality, breathing_problem,
noise_level, living_conditions, safety, basic_needs,
academic_performance, study_load, teacher_student_relationship,
future_career_concerns, social_support, peer_pressure,
extracurricular_activities, bullying, stress_level
) %>%
mutate(
self_esteem = (30) - self_esteem,
sleep_quality = (5) - sleep_quality,
living_conditions = (5) - living_conditions,
safety = (5) - safety,
basic_needs = (5) - basic_needs,
study_load = (5) - study_load,
future_career_concerns = (5) - future_career_concerns,
peer_pressure = (5) - peer_pressure,
extracurricular_activities = (5) - extracurricular_activities,
bullying = (5) - bullying
)
cat("\nVariabel yang digunakan:", ncol(sem_data), "\n")
##
## Variabel yang digunakan: 20
cat("Jumlah observasi :", nrow(sem_data), "\n")
## Jumlah observasi : 1100
# STATISTIK DESKRIPTIF
cat(" STATISTIK DESKRIPTIF\n")
## STATISTIK DESKRIPTIF
summary(sem_data)
## anxiety_level self_esteem mental_health_history depression
## Min. : 0.00 Min. : 0.00 Min. :0.0000 Min. : 0.00
## 1st Qu.: 6.00 1st Qu.: 4.00 1st Qu.:0.0000 1st Qu.: 6.00
## Median :11.00 Median :11.00 Median :0.0000 Median :12.00
## Mean :11.06 Mean :12.22 Mean :0.4927 Mean :12.56
## 3rd Qu.:16.00 3rd Qu.:19.00 3rd Qu.:1.0000 3rd Qu.:19.00
## Max. :21.00 Max. :30.00 Max. :1.0000 Max. :27.00
## headache sleep_quality breathing_problem noise_level
## Min. :0.000 Min. :0.00 Min. :0.000 Min. :0.000
## 1st Qu.:1.000 1st Qu.:1.00 1st Qu.:2.000 1st Qu.:2.000
## Median :3.000 Median :2.50 Median :3.000 Median :3.000
## Mean :2.508 Mean :2.34 Mean :2.754 Mean :2.649
## 3rd Qu.:3.000 3rd Qu.:4.00 3rd Qu.:4.000 3rd Qu.:3.000
## Max. :5.000 Max. :5.00 Max. :5.000 Max. :5.000
## living_conditions safety basic_needs academic_performance
## Min. :0.000 Min. :0.000 Min. :0.000 Min. :0.000
## 1st Qu.:2.000 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:2.000
## Median :3.000 Median :3.000 Median :2.000 Median :2.000
## Mean :2.482 Mean :2.263 Mean :2.227 Mean :2.773
## 3rd Qu.:3.000 3rd Qu.:3.000 3rd Qu.:3.000 3rd Qu.:4.000
## Max. :5.000 Max. :5.000 Max. :5.000 Max. :5.000
## study_load teacher_student_relationship future_career_concerns
## Min. :0.000 Min. :0.000 Min. :0.000
## 1st Qu.:2.000 1st Qu.:2.000 1st Qu.:1.000
## Median :3.000 Median :2.000 Median :3.000
## Mean :2.378 Mean :2.648 Mean :2.351
## 3rd Qu.:3.000 3rd Qu.:4.000 3rd Qu.:4.000
## Max. :5.000 Max. :5.000 Max. :5.000
## social_support peer_pressure extracurricular_activities bullying
## Min. :0.000 Min. :0.000 Min. :0.000 Min. :0.000
## 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:1.000 1st Qu.:1.000
## Median :2.000 Median :3.000 Median :2.500 Median :2.000
## Mean :1.882 Mean :2.265 Mean :2.233 Mean :2.383
## 3rd Qu.:3.000 3rd Qu.:3.000 3rd Qu.:3.000 3rd Qu.:4.000
## Max. :3.000 Max. :5.000 Max. :5.000 Max. :5.000
## stress_level
## Min. :0.0000
## 1st Qu.:0.0000
## Median :1.0000
## Mean :0.9964
## 3rd Qu.:2.0000
## Max. :2.0000
# VISUALISASI DISTRIBUSI
par(mfrow = c(4, 6), mar = c(3, 3, 2, 1))
for (col in names(sem_data)) {
hist(sem_data[[col]], main = col, col = "steelblue",
border = "white", xlab = "", cex.main = 0.75)
}
par(mfrow = c(1, 1))

par(mfrow = c(4, 6), mar = c(3, 3, 2, 1))
for (col in names(sem_data)) {
boxplot(sem_data[[col]], main = col, col = "#AED6F1",
border = "navy", cex.main = 0.75)
}
par(mfrow = c(1, 1))

# MATRIKS KORELASI
cor_matrix <- cor(sem_data, use = "complete.obs")
corrplot(
cor_matrix,
method = "color",
type = "upper",
tl.col = "black",
tl.cex = 0.4,
tl.srt = 45,
addCoef.col = "black",
number.cex = 0.25,
cl.cex = 0.8,
col = colorRampPalette(c("blue", "white", "red"))(200),
title = "Matriks Korelasi – Student Stress Factors",
mar = c(0, 0, 2, 0)
)

# DEFINISI sem_core
sem_core <- sem_data %>% select(-stress_level)
# UJI NORMALITAS MULTIVARIAT (MARDIA)
cat(" UJI NORMALITAS MULTIVARIAT (MARDIA)\n")
## UJI NORMALITAS MULTIVARIAT (MARDIA)
mardia_result <- mardia(sem_core)

print(mardia_result)
## Call: mardia(x = sem_core)
##
## Mardia tests of multivariate skew and kurtosis
## Use describe(x) the to get univariate tests
## n.obs = 1100 num.vars = 19
## b1p = 107.46 skew = 19700.84 with probability <= 0
## small sample skew = 19759.95 with probability <= 0
## b2p = 856.36 kurtosis = 268.49 with probability <= 0
skew_p <- mardia_result$skew.p
kurt_p <- mardia_result$kurtosis.p
if (isTRUE(!is.na(skew_p) && !is.na(kurt_p) && skew_p > 0.05 && kurt_p > 0.05)) {
cat("Kesimpulan: Data NORMAL Multivariat\n")
} else {
cat("Kesimpulan: Data TIDAK Normal Multivariat\n")
cat("-> Gunakan estimator MLR di lavaan\n")
}
## Kesimpulan: Data TIDAK Normal Multivariat
## -> Gunakan estimator MLR di lavaan
# Uji normalitas univariat
cat("\n── Normalitas Univariat per Variabel ──\n")
##
## ── Normalitas Univariat per Variabel ──
n_obs <- nrow(sem_core)
hasil_uji <- data.frame(
Variabel = names(sem_core),
Statistic = NA_real_,
P_value = NA_real_,
Status = NA_character_,
stringsAsFactors = FALSE
)
if (n_obs <= 5000) {
cat("(Shapiro-Wilk, n =", n_obs, ")\n\n")
for (i in seq_along(names(sem_core))) {
test <- shapiro.test(sem_core[[i]])
hasil_uji$Statistic[i] <- round(test$statistic, 4)
hasil_uji$P_value[i] <- round(test$p.value, 4)
hasil_uji$Status[i] <- ifelse(
test$p.value > 0.05, "Normal", "Tidak Normal")
}
} else {
cat("(Kolmogorov-Smirnov, n =", n_obs, ")\n\n")
for (i in seq_along(names(sem_core))) {
x <- scale(sem_core[[i]])
test <- ks.test(x, "pnorm")
hasil_uji$Statistic[i] <- round(test$statistic, 4)
hasil_uji$P_value[i] <- round(test$p.value, 4)
hasil_uji$Status[i] <- ifelse(
test$p.value > 0.05, "Normal", "Tidak Normal")
}
}
## (Shapiro-Wilk, n = 1100 )
print(hasil_uji)
## Variabel Statistic P_value Status
## 1 anxiety_level 0.9580 0 Tidak Normal
## 2 self_esteem 0.9325 0 Tidak Normal
## 3 mental_health_history 0.6365 0 Tidak Normal
## 4 depression 0.9589 0 Tidak Normal
## 5 headache 0.9023 0 Tidak Normal
## 6 sleep_quality 0.8854 0 Tidak Normal
## 7 breathing_problem 0.9149 0 Tidak Normal
## 8 noise_level 0.9257 0 Tidak Normal
## 9 living_conditions 0.9279 0 Tidak Normal
## 10 safety 0.9116 0 Tidak Normal
## 11 basic_needs 0.9134 0 Tidak Normal
## 12 academic_performance 0.9064 0 Tidak Normal
## 13 study_load 0.9259 0 Tidak Normal
## 14 teacher_student_relationship 0.9188 0 Tidak Normal
## 15 future_career_concerns 0.8859 0 Tidak Normal
## 16 social_support 0.7972 0 Tidak Normal
## 17 peer_pressure 0.9089 0 Tidak Normal
## 18 extracurricular_activities 0.9134 0 Tidak Normal
## 19 bullying 0.8914 0 Tidak Normal
cat("\nCatatan: Estimator MLR robust terhadap non-normalitas.\n")
##
## Catatan: Estimator MLR robust terhadap non-normalitas.
# UJI KMO
cat("UJI KMO\n")
## UJI KMO
cor_core <- cor(sem_core, use = "complete.obs")
kmo_result <- KMO(cor_core)
print(kmo_result)
## Kaiser-Meyer-Olkin factor adequacy
## Call: KMO(r = cor_core)
## Overall MSA = 0.98
## MSA for each item =
## anxiety_level self_esteem
## 0.99 0.98
## mental_health_history depression
## 0.99 0.99
## headache sleep_quality
## 0.98 0.98
## breathing_problem noise_level
## 0.98 0.99
## living_conditions safety
## 0.99 0.98
## basic_needs academic_performance
## 0.98 0.98
## study_load teacher_student_relationship
## 0.99 0.98
## future_career_concerns social_support
## 0.98 0.96
## peer_pressure extracurricular_activities
## 0.98 0.98
## bullying
## 0.98
msa <- kmo_result$MSA
if (msa >= 0.90) {
cat("MSA =", round(msa, 3), "-> Marvelous (Sangat Layak)\n")
} else if (msa >= 0.80) {
cat("MSA =", round(msa, 3), "-> Meritorious (Layak)\n")
} else if (msa >= 0.70) {
cat("MSA =", round(msa, 3), "-> Middling (Cukup Layak)\n")
} else if (msa >= 0.60) {
cat("MSA =", round(msa, 3), "-> Mediocre (Pas-pasan)\n")
} else if (msa >= 0.50) {
cat("MSA =", round(msa, 3), "-> Miserable (Hampir Tidak Layak)\n")
} else {
cat("MSA =", round(msa, 3), "-> Tidak Layak untuk SEM\n")
}
## MSA = 0.983 -> Marvelous (Sangat Layak)
# UJI BARTLETT
cat(" UJI BARTLETT\n")
## UJI BARTLETT
bartlett_result <- cortest.bartlett(cor_core, n = nrow(sem_core))
bartlett_result
## $chisq
## [1] 16086.67
##
## $p.value
## [1] 0
##
## $df
## [1] 171
if (bartlett_result$p.value < 0.05) {
cat("Kesimpulan: p < 0.05 -> Data LAYAK untuk analisis SEM\n")
} else {
cat("Kesimpulan: p >= 0.05 -> Data tidak layak untuk SEM\n")
}
## Kesimpulan: p < 0.05 -> Data LAYAK untuk analisis SEM
# Uji Multikulinearitas
model_vif <- lm(
anxiety_level ~ self_esteem + depression +
headache + sleep_quality + breathing_problem +
study_load + academic_performance + future_career_concerns +
peer_pressure + bullying + extracurricular_activities,
data = sem_core
)
vif(model_vif)
## self_esteem depression
## 2.736896 2.947854
## headache sleep_quality
## 2.390172 2.865135
## breathing_problem study_load
## 1.678886 1.864410
## academic_performance future_career_concerns
## 2.404494 3.231987
## peer_pressure bullying
## 2.382107 2.995177
## extracurricular_activities
## 2.357690
max_vif <- max(vif(model_vif))
if (max_vif < 5) {
cat("Kesimpulan: nilai VIF maksimum =", round(max_vif, 3),
"-> Tidak terdapat masalah multikolinearitas (layak untuk SEM)\n")
} else {
cat("Kesimpulan: nilai VIF maksimum =", round(max_vif, 3),
"-> Terdapat multikolinearitas (perlu perbaikan model)\n")
}
## Kesimpulan: nilai VIF maksimum = 3.232 -> Tidak terdapat masalah multikolinearitas (layak untuk SEM)
# STANDARDISASI DATA
cat("\n── Standardisasi Data ──\n")
##
## ── Standardisasi Data ──
sem_core_scaled <- as.data.frame(scale(sem_core))
sem_data_scaled <- as.data.frame(scale(sem_data))
cat("Mean tiap variabel (harus ~0):\n")
## Mean tiap variabel (harus ~0):
print(round(colMeans(sem_core_scaled), 3))
## anxiety_level self_esteem
## 0 0
## mental_health_history depression
## 0 0
## headache sleep_quality
## 0 0
## breathing_problem noise_level
## 0 0
## living_conditions safety
## 0 0
## basic_needs academic_performance
## 0 0
## study_load teacher_student_relationship
## 0 0
## future_career_concerns social_support
## 0 0
## peer_pressure extracurricular_activities
## 0 0
## bullying
## 0
cat("\nSD tiap variabel (harus ~1):\n")
##
## SD tiap variabel (harus ~1):
print(round(apply(sem_core_scaled, 2, sd), 3))
## anxiety_level self_esteem
## 1 1
## mental_health_history depression
## 1 1
## headache sleep_quality
## 1 1
## breathing_problem noise_level
## 1 1
## living_conditions safety
## 1 1
## basic_needs academic_performance
## 1 1
## study_load teacher_student_relationship
## 1 1
## future_career_concerns social_support
## 1 1
## peer_pressure extracurricular_activities
## 1 1
## bullying
## 1
# MODEL CFA
cat("CONFIRMATORY FACTOR ANALYSIS (CFA)\n")
## CONFIRMATORY FACTOR ANALYSIS (CFA)
cfa_model <- '
Stress =~ anxiety_level + depression + self_esteem +
sleep_quality + peer_pressure + bullying +
academic_performance + study_load
'
fit_cfa <- cfa(
cfa_model,
data = sem_core_scaled,
estimator = "MLR"
)
cat("\nKonvergen CFA?", lavInspect(fit_cfa, "converged"), "\n")
##
## Konvergen CFA? TRUE
summary(fit_cfa, fit.measures = TRUE, standardized = TRUE)
## lavaan 0.6-21 ended normally after 23 iterations
##
## Estimator ML
## Optimization method NLMINB
## Number of model parameters 16
##
## Number of observations 1100
##
## Model Test User Model:
## Standard Scaled
## Test Statistic 67.196 25.091
## Degrees of freedom 20 20
## P-value (Chi-square) 0.000 0.198
## Scaling correction factor 2.678
## Yuan-Bentler correction (Mplus variant)
##
## Model Test Baseline Model:
##
## Test statistic 6156.303 2416.179
## Degrees of freedom 28 28
## P-value 0.000 0.000
## Scaling correction factor 2.548
##
## User Model versus Baseline Model:
##
## Comparative Fit Index (CFI) 0.992 0.998
## Tucker-Lewis Index (TLI) 0.989 0.997
##
## Robust Comparative Fit Index (CFI) 0.998
## Robust Tucker-Lewis Index (TLI) 0.997
##
## Loglikelihood and Information Criteria:
##
## Loglikelihood user model (H0) -9438.104 -9438.104
## Scaling correction factor 1.346
## for the MLR correction
## Loglikelihood unrestricted model (H1) -9404.506 -9404.506
## Scaling correction factor 2.086
## for the MLR correction
##
## Akaike (AIC) 18908.207 18908.207
## Bayesian (BIC) 18988.256 18988.256
## Sample-size adjusted Bayesian (SABIC) 18937.436 18937.436
##
## Root Mean Square Error of Approximation:
##
## RMSEA 0.046 0.015
## 90 Percent confidence interval - lower 0.034 0.000
## 90 Percent confidence interval - upper 0.059 0.026
## P-value H_0: RMSEA <= 0.050 0.669 1.000
## P-value H_0: RMSEA >= 0.080 0.000 0.000
##
## Robust RMSEA 0.025
## 90 Percent confidence interval - lower 0.000
## 90 Percent confidence interval - upper 0.052
## P-value H_0: Robust RMSEA <= 0.050 0.935
## P-value H_0: Robust RMSEA >= 0.080 0.000
##
## Standardized Root Mean Square Residual:
##
## SRMR 0.015 0.015
##
## Parameter Estimates:
##
## Standard errors Sandwich
## Information bread Observed
## Observed information based on Hessian
##
## Latent Variables:
## Estimate Std.Err z-value P(>|z|) Std.lv Std.all
## Stress =~
## anxiety_level 1.000 0.842 0.842
## depression 0.985 0.025 39.855 0.000 0.829 0.830
## self_esteem 0.954 0.024 39.786 0.000 0.803 0.804
## sleep_quality 0.995 0.021 46.297 0.000 0.837 0.838
## peer_pressure -0.910 0.024 -37.503 0.000 -0.766 -0.767
## bullying -0.987 0.021 -46.609 0.000 -0.831 -0.832
## acadmc_prfrmnc -0.923 0.024 -38.853 0.000 -0.777 -0.778
## study_load -0.827 0.026 -32.293 0.000 -0.697 -0.697
##
## Variances:
## Estimate Std.Err z-value P(>|z|) Std.lv Std.all
## .anxiety_level 0.290 0.021 14.101 0.000 0.290 0.291
## .depression 0.312 0.022 14.029 0.000 0.312 0.312
## .self_esteem 0.354 0.025 14.174 0.000 0.354 0.354
## .sleep_quality 0.298 0.023 12.703 0.000 0.298 0.298
## .peer_pressure 0.412 0.029 14.184 0.000 0.412 0.412
## .bullying 0.308 0.025 12.541 0.000 0.308 0.308
## .acadmc_prfrmnc 0.395 0.026 15.165 0.000 0.395 0.395
## .study_load 0.514 0.030 16.998 0.000 0.514 0.514
## Stress 0.709 0.030 23.440 0.000 1.000 1.000
cat("\n── Indeks Fit CFA ──\n")
##
## ── Indeks Fit CFA ──
round(fitMeasures(fit_cfa, c(
"chisq", "cfi", "tli", "rmsea", "srmr"
)), 3)
## chisq cfi tli rmsea srmr
## 67.196 0.992 0.989 0.046 0.015
# EVALUASI OUTER MODEL
cat(" EVALUASI OUTER MODEL\n")
## EVALUASI OUTER MODEL
# Loading Factor
std_sol <- standardizedSolution(fit_cfa) %>%
filter(op == "=~") %>%
select(lhs, rhs, est.std, pvalue) %>%
rename(
Konstruk = lhs,
Indikator = rhs,
Loading = est.std,
P_value = pvalue
) %>%
mutate(
Status = ifelse(abs(Loading) >= 0.70, "✓ Valid", "✗ Perlu ditinjau")
)
cat("\n── Loading Factor (ideal >= 0.70) ──\n")
##
## ── Loading Factor (ideal >= 0.70) ──
print(std_sol)
## Konstruk Indikator Loading P_value Status
## 1 Stress anxiety_level 0.842 0 ✓ Valid
## 2 Stress depression 0.830 0 ✓ Valid
## 3 Stress self_esteem 0.804 0 ✓ Valid
## 4 Stress sleep_quality 0.838 0 ✓ Valid
## 5 Stress peer_pressure -0.767 0 ✓ Valid
## 6 Stress bullying -0.832 0 ✓ Valid
## 7 Stress academic_performance -0.778 0 ✓ Valid
## 8 Stress study_load -0.697 0 ✗ Perlu ditinjau
# AVE – menggunakan nilai absolut loading
ave_df <- std_sol %>%
group_by(Konstruk) %>%
summarise(
AVE = mean(Loading^2, na.rm = TRUE),
Status = ifelse(mean(Loading^2, na.rm = TRUE) >= 0.50,
"✓ Valid", "✗ < 0.50"),
.groups = "drop"
)
cat("\n── AVE (ideal >= 0.50) ──\n")
##
## ── AVE (ideal >= 0.50) ──
print(ave_df)
## # A tibble: 1 × 3
## Konstruk AVE Status
## <chr> <dbl> <chr>
## 1 Stress 0.639 ✓ Valid
# Composite Reliability – formula yang benar menggunakan abs(loading)
cr_df <- std_sol %>%
group_by(Konstruk) %>%
summarise(
sum_lam = sum(abs(Loading), na.rm = TRUE),
sum_lam2 = sum(Loading^2, na.rm = TRUE),
n_item = n(),
CR = sum_lam^2 / (sum_lam^2 + (n_item - sum_lam2)),
Status = ifelse(CR >= 0.70, "✓ Reliabel", "✗ < 0.70"),
.groups = "drop"
)
cat("\n── Composite Reliability (ideal >= 0.70) ──\n")
##
## ── Composite Reliability (ideal >= 0.70) ──
print(cr_df)
## # A tibble: 1 × 6
## Konstruk sum_lam sum_lam2 n_item CR Status
## <chr> <dbl> <dbl> <int> <dbl> <chr>
## 1 Stress 6.39 5.12 8 0.934 ✓ Reliabel
# CRONBACH'S ALPHA
alpha_stress <- psych::alpha(
sem_core %>%
select(anxiety_level, depression, self_esteem,
sleep_quality, peer_pressure, bullying,
academic_performance, study_load),
check.keys = TRUE
)
## Warning in psych::alpha(sem_core %>% select(anxiety_level, depression, self_esteem, : Some items were negatively correlated with the first principal component and were automatically reversed.
## This is indicated by a negative sign for the variable name.
alpha_summary <- data.frame(
Konstruk = "Stress",
Alpha = round(alpha_stress$total$raw_alpha, 3),
Status = ifelse(alpha_stress$total$raw_alpha >= 0.70,
"✓ Reliabel", "✗ < 0.70")
)
print(alpha_summary)
## Konstruk Alpha Status
## 1 Stress 0.819 ✓ Reliabel
cat("\n── Cronbach's Alpha (CONSISTENT WITH CFA) ──\n")
##
## ── Cronbach's Alpha (CONSISTENT WITH CFA) ──
print(alpha_summary)
## Konstruk Alpha Status
## 1 Stress 0.819 ✓ Reliabel
# korelasi latent (lebih aman pakai standardized solution)
cat("\n── VARIANCE LATENT (Stress) ──\n")
##
## ── VARIANCE LATENT (Stress) ──
lavInspect(fit_cfa, "cov.lv")
## Stress
## Stress 0.709
# Visualisasi CFA
semPaths(
fit_cfa,
what = "std",
layout = "tree",
edge.label.cex = 0.8,
label.cex = 1.2,
sizeMan = 6,
sizeLat = 10,
nCharNodes = 0,
style = "lisrel",
color = list(lat = "#AED6F1", man = "#FDEBD0")
)
title("Path Diagram – CFA", line = 3)

cat("\n── FIT MODEL SUMMARY ──\n")
##
## ── FIT MODEL SUMMARY ──
fitMeasures(fit_cfa, c("cfi","tli","rmsea","srmr"))
## cfi tli rmsea srmr
## 0.992 0.989 0.046 0.015
# MODEL SEM FULL
cat("\n=== SEM MODEL ===\n")
##
## === SEM MODEL ===
sem_model <- '
Stress =~ anxiety_level + depression + self_esteem +
sleep_quality + headache + breathing_problem +
academic_performance + study_load +
peer_pressure + bullying
stress_level ~ Stress
'
fit_sem <- sem(sem_model, data = sem_data_scaled, estimator = "MLR")
summary(fit_sem, fit.measures = TRUE, standardized = TRUE, rsquare = TRUE)
## lavaan 0.6-21 ended normally after 31 iterations
##
## Estimator ML
## Optimization method NLMINB
## Number of model parameters 22
##
## Number of observations 1100
##
## Model Test User Model:
## Standard Scaled
## Test Statistic 142.396 51.305
## Degrees of freedom 44 44
## P-value (Chi-square) 0.000 0.209
## Scaling correction factor 2.775
## Yuan-Bentler correction (Mplus variant)
##
## Model Test Baseline Model:
##
## Test statistic 9305.440 3508.510
## Degrees of freedom 55 55
## P-value 0.000 0.000
## Scaling correction factor 2.652
##
## User Model versus Baseline Model:
##
## Comparative Fit Index (CFI) 0.989 0.998
## Tucker-Lewis Index (TLI) 0.987 0.997
##
## Robust Comparative Fit Index (CFI) 0.998
## Robust Tucker-Lewis Index (TLI) 0.997
##
## Loglikelihood and Information Criteria:
##
## Loglikelihood user model (H0) -12582.131 -12582.131
## Scaling correction factor 1.306
## for the MLR correction
## Loglikelihood unrestricted model (H1) -12510.934 -12510.934
## Scaling correction factor 2.286
## for the MLR correction
##
## Akaike (AIC) 25208.263 25208.263
## Bayesian (BIC) 25318.330 25318.330
## Sample-size adjusted Bayesian (SABIC) 25248.453 25248.453
##
## Root Mean Square Error of Approximation:
##
## RMSEA 0.045 0.012
## 90 Percent confidence interval - lower 0.037 0.000
## 90 Percent confidence interval - upper 0.053 0.020
## P-value H_0: RMSEA <= 0.050 0.827 1.000
## P-value H_0: RMSEA >= 0.080 0.000 0.000
##
## Robust RMSEA 0.020
## 90 Percent confidence interval - lower 0.000
## 90 Percent confidence interval - upper 0.041
## P-value H_0: Robust RMSEA <= 0.050 0.995
## P-value H_0: Robust RMSEA >= 0.080 0.000
##
## Standardized Root Mean Square Residual:
##
## SRMR 0.016 0.016
##
## Parameter Estimates:
##
## Standard errors Sandwich
## Information bread Observed
## Observed information based on Hessian
##
## Latent Variables:
## Estimate Std.Err z-value P(>|z|) Std.lv Std.all
## Stress =~
## anxiety_level 1.000 0.834 0.834
## depression 0.991 0.023 42.261 0.000 0.826 0.827
## self_esteem 0.974 0.023 43.040 0.000 0.812 0.812
## sleep_quality 1.000 0.020 50.062 0.000 0.834 0.835
## headache 0.928 0.023 40.613 0.000 0.774 0.775
## breathng_prblm 0.772 0.023 33.386 0.000 0.643 0.644
## acadmc_prfrmnc -0.941 0.023 -40.862 0.000 -0.785 -0.785
## study_load -0.836 0.025 -33.930 0.000 -0.697 -0.697
## peer_pressure -0.922 0.023 -39.771 0.000 -0.769 -0.769
## bullying -0.995 0.020 -49.241 0.000 -0.830 -0.830
##
## Regressions:
## Estimate Std.Err z-value P(>|z|) Std.lv Std.all
## stress_level ~
## Stress 1.083 0.019 56.076 0.000 0.903 0.904
##
## Variances:
## Estimate Std.Err z-value P(>|z|) Std.lv Std.all
## .anxiety_level 0.304 0.021 14.675 0.000 0.304 0.304
## .depression 0.317 0.022 14.579 0.000 0.317 0.317
## .self_esteem 0.340 0.022 15.472 0.000 0.340 0.340
## .sleep_quality 0.303 0.022 13.607 0.000 0.303 0.304
## .headache 0.400 0.026 15.658 0.000 0.400 0.400
## .breathng_prblm 0.585 0.026 22.282 0.000 0.585 0.586
## .acadmc_prfrmnc 0.383 0.025 15.434 0.000 0.383 0.383
## .study_load 0.513 0.029 17.689 0.000 0.513 0.514
## .peer_pressure 0.408 0.026 15.481 0.000 0.408 0.409
## .bullying 0.310 0.024 13.188 0.000 0.310 0.311
## .stress_level 0.183 0.018 10.290 0.000 0.183 0.183
## Stress 0.695 0.030 23.520 0.000 1.000 1.000
##
## R-Square:
## Estimate
## anxiety_level 0.696
## depression 0.683
## self_esteem 0.660
## sleep_quality 0.696
## headache 0.600
## breathng_prblm 0.414
## acadmc_prfrmnc 0.617
## study_load 0.486
## peer_pressure 0.591
## bullying 0.689
## stress_level 0.817
# EVALUASI INNER MODEL
cat(" EVALUASI INNER MODEL\n")
## EVALUASI INNER MODEL
fit_idx <- fitMeasures(fit_sem, c("cfi","tli","rmsea","srmr"))
print(round(fit_idx, 3))
## cfi tli rmsea srmr
## 0.989 0.987 0.045 0.016
cat("\n── Panduan Interpretasi Fit ──\n")
##
## ── Panduan Interpretasi Fit ──
cat("CFI / TLI >= 0.90 -> Fit Baik\n")
## CFI / TLI >= 0.90 -> Fit Baik
cat("RMSEA < 0.08 -> Fit Baik (≤0.05 sangat baik)\n")
## RMSEA < 0.08 -> Fit Baik (≤0.05 sangat baik)
cat("SRMR < 0.08 -> Fit Baik\n")
## SRMR < 0.08 -> Fit Baik
cat("p-value > 0.05 -> Fit sempurna (jarang terjadi di SEM)\n")
## p-value > 0.05 -> Fit sempurna (jarang terjadi di SEM)
# Path Coefficient
cat("\n── Path Coefficients (Inner Model) ──\n")
##
## ── Path Coefficients (Inner Model) ──
param_est <- parameterEstimates(fit_sem, standardized = TRUE) %>%
filter(op == "~") %>%
select(lhs, rhs, est, se, z, pvalue, std.all) %>%
mutate(Signif = ifelse(pvalue <= 0.05, "Signifikan", "Tidak"))
print(param_est)
## lhs rhs est se z pvalue std.all Signif
## 1 stress_level Stress 1.083 0.019 56.076 0 0.904 Signifikan
# R-Square
r2 <- lavInspect(fit_sem, "r2")
cat("R2 stress_level =", r2, "\n")
## R2 stress_level = 0.6959758 0.6831484 0.6597558 0.6964134 0.5999818 0.4143845 0.6165643 0.4863267 0.5912141 0.6893363 0.8166506
if (!is.null(r2) && "stress_level" %in% names(r2)) {
cat("R² stress_level =", round(r2["stress_level"], 3), "\n")
r2_val <- r2["stress_level"]
cat("Interpretasi: ")
if (r2_val < 0.25) {
cat("Rendah (lemah)\n")
} else if (r2_val < 0.50) {
cat("Sedang\n")
} else if (r2_val < 0.75) {
cat("Tinggi\n")
} else {
cat("Sangat tinggi\n")
}
cat("→ Menunjukkan proporsi variansi stress_level yang dijelaskan oleh variabel eksogen.\n")
} else {
cat("R² tidak ditemukan atau nama variabel tidak sesuai.\n")
}
## R² stress_level = 0.817
## Interpretasi: Sangat tinggi
## → Menunjukkan proporsi variansi stress_level yang dijelaskan oleh variabel eksogen.
# VISUALISASI PATH DIAGRAM SEM
semPaths(
fit_sem,
what = "std",
layout = "tree",
edge.label.cex = 0.8,
label.cex = 1.2,
sizeMan = 6,
sizeLat = 10,
nCharNodes = 0,
residuals = FALSE,
style = "lisrel",
color = list(
lat = "#AED6F1",
man = "#FDEBD0"
)
)
title("Path Diagram – Full SEM", line = 3)
