1 Install and Load Library

library(lavaan)
library(semPlot)
library(psych)
library(car)
library(ggplot2)
library(dplyr)

2 Preprocessing Data

2.1 Load Data

data <- read.csv("StressLevelDataset.csv", header = TRUE)

cat("Number of rows (respondents):", nrow(data), "\n")
## Number of rows (respondents): 1100
cat("Number of columns (variables):", ncol(data), "\n")
## Number of columns (variables): 21
cat("\nColumn names:\n")
## 
## Column names:
print(colnames(data))
##  [1] "anxiety_level"                "self_esteem"                 
##  [3] "mental_health_history"        "depression"                  
##  [5] "headache"                     "blood_pressure"              
##  [7] "sleep_quality"                "breathing_problem"           
##  [9] "noise_level"                  "living_conditions"           
## [11] "safety"                       "basic_needs"                 
## [13] "academic_performance"         "study_load"                  
## [15] "teacher_student_relationship" "future_career_concerns"      
## [17] "social_support"               "peer_pressure"               
## [19] "extracurricular_activities"   "bullying"                    
## [21] "stress_level"
head(data, 5)
##   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
##   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
##   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
##   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
##   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

2.2 Cek Missing Value

cat("Total NA in dataset:", sum(is.na(data)), "\n\n")
## Total NA in dataset: 0
cat("Percentage of NA per column:\n")
## Percentage of NA per column:
print(round(colMeans(is.na(data)) * 100, 2))
##                anxiety_level                  self_esteem 
##                            0                            0 
##        mental_health_history                   depression 
##                            0                            0 
##                     headache               blood_pressure 
##                            0                            0 
##                sleep_quality            breathing_problem 
##                            0                            0 
##                  noise_level            living_conditions 
##                            0                            0 
##                       safety                  basic_needs 
##                            0                            0 
##         academic_performance                   study_load 
##                            0                            0 
## teacher_student_relationship       future_career_concerns 
##                            0                            0 
##               social_support                peer_pressure 
##                            0                            0 
##   extracurricular_activities                     bullying 
##                            0                            0 
##                 stress_level 
##                            0

2.3 Remove Duplicate Data

duplicate_rows <- data[duplicated(data), ]
cat("Number of duplicate rows:", nrow(duplicate_rows), "\n")
## Number of duplicate rows: 0
if (nrow(duplicate_rows) > 0) {
  data <- data[!duplicated(data), ]
  cat("Duplicates removed. Remaining rows:", nrow(data), "\n")
} else {
  cat("No duplicates found, data remains intact.\n")
}
## No duplicates found, data remains intact.

2.4 Convert Variables to Numeric

data_numeric <- data
for (col in colnames(data_numeric)) {
  if (!is.numeric(data_numeric[[col]])) {
    data_numeric[[col]] <- as.numeric(as.factor(data_numeric[[col]]))
  }
}
cat("All columns successfully converted to numeric.\n")
## All columns successfully converted to numeric.
sapply(data_numeric, class)
##                anxiety_level                  self_esteem 
##                    "integer"                    "integer" 
##        mental_health_history                   depression 
##                    "integer"                    "integer" 
##                     headache               blood_pressure 
##                    "integer"                    "integer" 
##                sleep_quality            breathing_problem 
##                    "integer"                    "integer" 
##                  noise_level            living_conditions 
##                    "integer"                    "integer" 
##                       safety                  basic_needs 
##                    "integer"                    "integer" 
##         academic_performance                   study_load 
##                    "integer"                    "integer" 
## teacher_student_relationship       future_career_concerns 
##                    "integer"                    "integer" 
##               social_support                peer_pressure 
##                    "integer"                    "integer" 
##   extracurricular_activities                     bullying 
##                    "integer"                    "integer" 
##                 stress_level 
##                    "integer"

2.5 Invert Variabel Negatif

Columns depression and bullying have reversed meanings: high scores = bad condition. To maintain consistency with the constructs (high scores = good condition), both variables are inverted.

cat("Range before inversion:\n")
## Range before inversion:
cat("  depression:", range(data_numeric$depression), "\n")
##   depression: 0 27
cat("  bullying  :", range(data_numeric$bullying),   "\n\n")
##   bullying  : 0 5
max_dep <- max(data_numeric$depression)
max_bul <- max(data_numeric$bullying)

data_numeric$depression_inv <- (max_dep + 1) - data_numeric$depression
data_numeric$bullying_inv   <- (max_bul + 1) - data_numeric$bullying

max_ap <- max(data_numeric$academic_performance)

data_numeric$academic_performance_inv <-
  (max_ap + 1) - data_numeric$academic_performance

max_mh <- max(data_numeric$mental_health_history)

data_numeric$mental_health_history_inv <-
  (max_mh + 1) - data_numeric$mental_health_history

max_extra <- max(data_numeric$extracurricular_activities)
data_numeric$extra_inv <- (max_extra + 1) - data_numeric$extracurricular_activities

cat("Range after inversion:\n")
## Range after inversion:
cat("  depression_inv:", range(data_numeric$depression_inv), "\n")
##   depression_inv: 1 28
cat("  bullying_inv  :", range(data_numeric$bullying_inv),   "\n")
##   bullying_inv  : 1 6

2.6 Z-Score Normalization

Only the 13 indicators used in SEM are normalized. The stress_level column (classification label) is not included.

sem_columns <- c(
  # X1 - Academic Stress
  "anxiety_level", "study_load", "academic_performance_inv",
  "future_career_concerns", "peer_pressure",
  # X2 - Social Support
  "social_support", "teacher_student_relationship",
  "extra_inv", "bullying_inv",
  # Y  - Psychological Well-Being
  "self_esteem", "depression_inv",
"sleep_quality", "mental_health_history_inv"
)

data_sem <- data_numeric[, sem_columns]

data_z <- as.data.frame(lapply(data_sem, function(x) {
  (x - mean(x, na.rm = TRUE)) / sd(x, na.rm = TRUE)
}))

cat("Dimensions of data_z:", nrow(data_z), "rows x", ncol(data_z), "columns\n")
## Dimensions of data_z: 1100 rows x 13 columns
head(data_z, 3)
##   anxiety_level study_load academic_performance_inv future_career_concerns
## 1     0.4799895 -0.4725849               -0.1606629              0.2294460
## 2     0.6434534  1.0474249                1.2531706              1.5371694
## 3     0.1530617  0.2874200                0.5462539             -0.4244157
##   peer_pressure social_support teacher_student_relationship  extra_inv
## 1     0.1862492      0.1127876                    0.2540977 -0.1641743
## 2     0.8878731     -0.8415689                   -1.1903852 -1.5750470
## 3     0.1862492      0.1127876                    0.2540977  0.5412621
##   bullying_inv self_esteem depression_inv sleep_quality
## 1    0.4031938  0.24849937      0.2013010    -0.4262512
## 2   -1.5563636 -1.09309234     -0.3163638    -1.0720865
## 3    0.4031938  0.02490076     -0.1869476    -0.4262512
##   mental_health_history_inv
## 1                 0.9851107
## 2                -1.0141915
## 3                -1.0141915

3 Exploration and Descriptive Statistics

3.1 Statistical Summary

cat("Descriptive Statistics (before normalization)\n")
## Descriptive Statistics (before normalization)
summary(data_sem)
##  anxiety_level     study_load    academic_performance_inv
##  Min.   : 0.00   Min.   :0.000   Min.   :1.000           
##  1st Qu.: 6.00   1st Qu.:2.000   1st Qu.:2.000           
##  Median :11.00   Median :2.000   Median :4.000           
##  Mean   :11.06   Mean   :2.622   Mean   :3.227           
##  3rd Qu.:16.00   3rd Qu.:3.000   3rd Qu.:4.000           
##  Max.   :21.00   Max.   :5.000   Max.   :6.000           
##  future_career_concerns peer_pressure   social_support 
##  Min.   :0.000          Min.   :0.000   Min.   :0.000  
##  1st Qu.:1.000          1st Qu.:2.000   1st Qu.:1.000  
##  Median :2.000          Median :2.000   Median :2.000  
##  Mean   :2.649          Mean   :2.735   Mean   :1.882  
##  3rd Qu.:4.000          3rd Qu.:4.000   3rd Qu.:3.000  
##  Max.   :5.000          Max.   :5.000   Max.   :3.000  
##  teacher_student_relationship   extra_inv      bullying_inv    self_esteem   
##  Min.   :0.000                Min.   :1.000   Min.   :1.000   Min.   : 0.00  
##  1st Qu.:2.000                1st Qu.:2.000   1st Qu.:2.000   1st Qu.:11.00  
##  Median :2.000                Median :3.500   Median :3.000   Median :19.00  
##  Mean   :2.648                Mean   :3.233   Mean   :3.383   Mean   :17.78  
##  3rd Qu.:4.000                3rd Qu.:4.000   3rd Qu.:5.000   3rd Qu.:26.00  
##  Max.   :5.000                Max.   :6.000   Max.   :6.000   Max.   :30.00  
##  depression_inv  sleep_quality  mental_health_history_inv
##  Min.   : 1.00   Min.   :0.00   Min.   :1.000            
##  1st Qu.: 9.00   1st Qu.:1.00   1st Qu.:1.000            
##  Median :16.00   Median :2.50   Median :2.000            
##  Mean   :15.44   Mean   :2.66   Mean   :1.507            
##  3rd Qu.:22.00   3rd Qu.:4.00   3rd Qu.:2.000            
##  Max.   :28.00   Max.   :5.00   Max.   :2.000

3.2 Skewness And Kurtosis

desc <- describe(data_sem)
round(desc[, c("mean", "sd", "skew", "kurtosis", "min", "max")], 3)
##                               mean   sd  skew kurtosis min max
## anxiety_level                11.06 6.12 -0.08    -1.10   0  21
## study_load                    2.62 1.32  0.23    -0.67   0   5
## academic_performance_inv      3.23 1.42 -0.18    -1.07   1   6
## future_career_concerns        2.65 1.53  0.20    -1.30   0   5
## peer_pressure                 2.73 1.43  0.19    -1.01   0   5
## social_support                1.88 1.05 -0.18    -1.44   0   3
## teacher_student_relationship  2.65 1.39  0.20    -0.91   0   5
## extra_inv                     3.23 1.42 -0.14    -1.04   1   6
## bullying_inv                  3.38 1.53 -0.17    -1.28   1   6
## self_esteem                  17.78 8.95 -0.40    -1.07   0  30
## depression_inv               15.45 7.73 -0.22    -0.99   1  28
## sleep_quality                 2.66 1.55  0.18    -1.32   0   5
## mental_health_history_inv     1.51 0.50 -0.03    -2.00   1   2

3.3 Histogram of All SEM Variables

par(mfrow = c(3, 5), mar = c(3, 3, 2, 1))
for (col in sem_columns) {
  hist(data_sem[[col]],
       main   = col,
       xlab   = "",
       col    = "steelblue",
       border = "white",
       cex.main = 0.85)
}
par(mfrow = c(1, 1))


4 Assumption Testing

4.1 Multivariate Normality Test (Mardia)

Mardia’s test is used to determine whether the data meet the multivariate normality assumption required in CB-SEM.

mardia_result <- mardia(data_z, plot = FALSE)

cat("Mardia Skewness  :", round(mardia_result$skew,   4), "\n")
## Mardia Skewness  : 10214.72
cat("Mardia Kurtosis  :", round(mardia_result$kurtosis, 4), "\n")
## Mardia Kurtosis  : 173.3041
cat("p-value Skewness :", round(mardia_result$p.skew,  4), "\n")
## p-value Skewness : 0
cat("p-value Kurtosis :", round(mardia_result$p.kurt,  4), "\n\n")
## p-value Kurtosis : 0
if (mardia_result$p.skew > 0.05 & mardia_result$p.kurt > 0.05) {
  cat("Conclusion: The data MEET the multivariate normality assumption (p > 0.05)\n")
} else {
  cat("Conclusion: The data DO NOT meet multivariate normality.\n")
  cat("Note: SEM can still proceed due to the large sample size (n=1100).\n")
  cat("Robust estimators (MLR) may be considered.\n")
}
## Conclusion: The data DO NOT meet multivariate normality.
## Note: SEM can still proceed due to the large sample size (n=1100).
## Robust estimators (MLR) may be considered.

4.2 Sampling Adequacy Test (KMO)

r_matrix   <- cor(data_z, use = "complete.obs")
kmo_result <- KMO(r_matrix)

cat("Overall MSA (KMO):", round(kmo_result$MSA, 4), "\n\n")
## Overall MSA (KMO): 0.9741
cat("KMO for each variable:\n")
## KMO for each variable:
print(round(kmo_result$MSAi, 4))
##                anxiety_level                   study_load 
##                       0.9787                       0.9831 
##     academic_performance_inv       future_career_concerns 
##                       0.9783                       0.9766 
##                peer_pressure               social_support 
##                       0.9782                       0.9474 
## teacher_student_relationship                    extra_inv 
##                       0.9629                       0.9818 
##                 bullying_inv                  self_esteem 
##                       0.9742                       0.9657 
##               depression_inv                sleep_quality 
##                       0.9783                       0.9750 
##    mental_health_history_inv 
##                       0.9835
cat("\n")
if (kmo_result$MSA >= 0.5) {
  cat("Conclusion: KMO ≥ 0.5 — sampling adequacy is satisfied\n")
} else {
  cat("Conclusion: KMO < 0.5 — sampling adequacy is not satisfied\n")
}
## Conclusion: KMO ≥ 0.5 — sampling adequacy is satisfied

4.3 Multicollinearity Test (VIF)

data_z_clean <- na.omit(data_z)

model_vif <- lm(
  self_esteem ~ anxiety_level + study_load + academic_performance_inv +
    future_career_concerns + peer_pressure +
    social_support + teacher_student_relationship +
    extra_inv + bullying_inv +
    depression_inv + sleep_quality,
  data = data_z_clean
)

vif_values <- vif(model_vif)

cat("VIF values:\n")
## VIF values:
print(round(vif_values, 3))
##                anxiety_level                   study_load 
##                        3.028                        1.852 
##     academic_performance_inv       future_career_concerns 
##                        2.447                        3.132 
##                peer_pressure               social_support 
##                        2.345                        2.126 
## teacher_student_relationship                    extra_inv 
##                        2.894                        2.319 
##                 bullying_inv               depression_inv 
##                        3.019                        2.973 
##                sleep_quality 
##                        2.954
problematic <- vif_values[vif_values > 5]

cat("\n")
if (length(problematic) == 0) {
  cat("Conclusion: All VIF values are < 5 — no problematic multicollinearity\n")
} else {
  cat("VIF > 5 found in variables:", names(problematic), "\n")
}
## Conclusion: All VIF values are < 5 — no problematic multicollinearity

Note: Safe VIF values are < 3.3 (strict) or < 5 (moderate). Values above 5 require attention, and above 10 are problematic.


5 CFA — Academic Stress (X1)

Construct: AcademicStress
Indicators: anxiety_level, study_load, academic_performance_inv, future_career_concerns, peer_pressure

model_cfa_x1 <- '
  AcademicStress =~ anxiety_level + study_load + academic_performance_inv +
                     future_career_concerns + peer_pressure
'

fit_x1 <- cfa(
  model_cfa_x1,
  data = data_z,
  std.lv = TRUE,
  estimator = "MLR"
)

5.1 CFA X1 Summary

summary(fit_x1, fit.measures = TRUE, standardized = TRUE)
## lavaan 0.6-21 ended normally after 18 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        10
## 
##   Number of observations                          1100
## 
## Model Test User Model:
##                                               Standard      Scaled
##   Test Statistic                                 7.155       2.829
##   Degrees of freedom                                 5           5
##   P-value (Chi-square)                           0.209       0.726
##   Scaling correction factor                                  2.529
##     Yuan-Bentler correction (Mplus variant)                       
## 
## Model Test Baseline Model:
## 
##   Test statistic                              2919.113    1186.203
##   Degrees of freedom                                10          10
##   P-value                                        0.000       0.000
##   Scaling correction factor                                  2.461
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    0.999       1.000
##   Tucker-Lewis Index (TLI)                       0.999       1.004
##                                                                   
##   Robust Comparative Fit Index (CFI)                         1.000
##   Robust Tucker-Lewis Index (TLI)                            1.004
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -6345.682   -6345.682
##   Scaling correction factor                                  1.440
##       for the MLR correction                                      
##   Loglikelihood unrestricted model (H1)      -6342.104   -6342.104
##   Scaling correction factor                                  1.803
##       for the MLR correction                                      
##                                                                   
##   Akaike (AIC)                               12711.363   12711.363
##   Bayesian (BIC)                             12761.394   12761.394
##   Sample-size adjusted Bayesian (SABIC)      12729.631   12729.631
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.020       0.000
##   90 Percent confidence interval - lower         0.000       0.000
##   90 Percent confidence interval - upper         0.050       0.015
##   P-value H_0: RMSEA <= 0.050                    0.953       1.000
##   P-value H_0: RMSEA >= 0.080                    0.000       0.000
##                                                                   
##   Robust RMSEA                                               0.000
##   90 Percent confidence interval - lower                     0.000
##   90 Percent confidence interval - upper                     0.049
##   P-value H_0: Robust RMSEA <= 0.050                         0.955
##   P-value H_0: Robust RMSEA >= 0.080                         0.002
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.008       0.008
## 
## 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
##   AcademicStress =~                                                      
##     anxiety_level      0.845    0.020   42.624    0.000    0.845    0.845
##     study_load         0.689    0.023   29.851    0.000    0.689    0.690
##     acdmc_prfrmnc_     0.755    0.021   36.288    0.000    0.755    0.755
##     ftr_crr_cncrns     0.851    0.019   45.542    0.000    0.851    0.852
##     peer_pressure      0.769    0.020   37.802    0.000    0.769    0.769
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .anxiety_level     0.285    0.026   11.157    0.000    0.285    0.285
##    .study_load        0.524    0.034   15.317    0.000    0.524    0.525
##    .acdmc_prfrmnc_    0.429    0.032   13.616    0.000    0.429    0.430
##    .ftr_crr_cncrns    0.275    0.029    9.540    0.000    0.275    0.275
##    .peer_pressure     0.408    0.031   13.307    0.000    0.408    0.408
##     AcademicStress    1.000                               1.000    1.000

5.2 Fit Indices CFA X1

fi_x1 <- fitMeasures(fit_x1, c("chisq", "df", "pvalue", "cfi", "tli", "rmsea", "srmr"))
print(round(fi_x1, 4))
##  chisq     df pvalue    cfi    tli  rmsea   srmr 
##  7.155  5.000  0.209  0.999  0.999  0.020  0.008
cfi_x1   <- fitMeasures(fit_x1, "cfi")
tli_x1   <- fitMeasures(fit_x1, "tli")
rmsea_x1 <- fitMeasures(fit_x1, "rmsea")
srmr_x1  <- fitMeasures(fit_x1, "srmr")

eval_x1 <- data.frame(
  Index    = c("CFI", "TLI", "RMSEA", "SRMR"),
  Value    = round(c(cfi_x1, tli_x1, rmsea_x1, srmr_x1), 4),
  Target   = c("≥ 0.90", "≥ 0.90", "< 0.08", "< 0.08"),
  Status   = c(
    ifelse(cfi_x1   >= 0.90, "PASS", "FAIL"),
    ifelse(tli_x1   >= 0.90, "PASS", "FAIL"),
    ifelse(rmsea_x1 <  0.08, "PASS", "FAIL"),
    ifelse(srmr_x1  <  0.08, "PASS", "FAIL")
  )
)
print(eval_x1)
##       Index  Value Target Status
## cfi     CFI 0.9993 ≥ 0.90   PASS
## tli     TLI 0.9985 ≥ 0.90   PASS
## rmsea RMSEA 0.0198 < 0.08   PASS
## srmr   SRMR 0.0081 < 0.08   PASS

5.3 CFA X1 Loading Factors

std_x1     <- standardizedSolution(fit_x1)
loading_x1 <- std_x1[std_x1$op == "=~", c("rhs", "est.std", "se", "pvalue")]
colnames(loading_x1) <- c("Indicator", "Std.Loading", "SE", "p-value")

loading_x1$Evaluation <- ifelse(
  abs(loading_x1$Std.Loading) >= 0.70, "Ideal (≥0.70)",
  ifelse(abs(loading_x1$Std.Loading) >= 0.50, "Acceptable (0.50–0.70)", "Weak (<0.50)")
)

loading_x1$Std.Loading <- round(loading_x1$Std.Loading, 4)
loading_x1$SE          <- round(loading_x1$SE, 4)
loading_x1$`p-value`   <- round(loading_x1$`p-value`, 4)

print(loading_x1[, 1:3])
##                  Indicator Std.Loading    SE
## 1            anxiety_level       0.846 0.015
## 2               study_load       0.690 0.020
## 3 academic_performance_inv       0.755 0.018
## 4   future_career_concerns       0.852 0.016
## 5            peer_pressure       0.769 0.018
cat("\n")
print(loading_x1[, c("Indicator", "Evaluation")])
##                  Indicator             Evaluation
## 1            anxiety_level          Ideal (≥0.70)
## 2               study_load Acceptable (0.50–0.70)
## 3 academic_performance_inv          Ideal (≥0.70)
## 4   future_career_concerns          Ideal (≥0.70)
## 5            peer_pressure          Ideal (≥0.70)

5.4 Composite Reliability and AVE X1

calculate_CR_AVE <- function(fit) {
  std    <- standardizedSolution(fit)
  lambda <- std$est.std[std$op == "=~"]
  theta  <- 1 - lambda^2
  CR     <- sum(lambda)^2 / (sum(lambda)^2 + sum(theta))
  AVE    <- sum(lambda^2)  / (sum(lambda^2)  + sum(theta))
  return(list(CR = CR, AVE = AVE))
}

cr_ave_x1 <- calculate_CR_AVE(fit_x1)
alpha_x1  <- psych::alpha(data_z[, c("anxiety_level", "study_load",
                                      "academic_performance_inv",
                                      "future_career_concerns", "peer_pressure")])

rel_x1 <- data.frame(
  Measure = c("Composite Reliability (CR)", "AVE", "Cronbach's Alpha"),
  Value   = round(c(cr_ave_x1$CR, cr_ave_x1$AVE, alpha_x1$total$raw_alpha), 4),
  Target  = c("≥ 0.70", "≥ 0.50", "≥ 0.70"),
  Status  = c(
    ifelse(cr_ave_x1$CR              >= 0.70, "PASS", "FAIL"),
    ifelse(cr_ave_x1$AVE             >= 0.50, "PASS", "FAIL"),
    ifelse(alpha_x1$total$raw_alpha  >= 0.70, "PASS", "FAIL")
  )
)
print(rel_x1)
##                      Measure  Value Target Status
## 1 Composite Reliability (CR) 0.8884 ≥ 0.70   PASS
## 2                        AVE 0.6156 ≥ 0.50   PASS
## 3           Cronbach's Alpha 0.8870 ≥ 0.70   PASS

5.5 CFA X1 Path Diagram

semPaths(
  object         = fit_x1,
  what           = "path",
  whatLabels     = "std",
  style          = "ram",
  layout         = "tree",
  rotation       = 2,
  sizeMan        = 7,
  sizeLat        = 8,
  edge.label.cex = 1.2,
  label.cex      = 1.1,
  color          = list(lat = "#AED6F1", man = "#A9DFBF"),
  mar            = c(3, 3, 3, 3)
)
title(main = "CFA — Academic Stress (X1)", cex.main = 1.3, font.main = 2)


6 CFA — Social Support (X2)

Construct: SocialSupport
Indicators: social_support, teacher_student_relationship, extracurricular_activities, bullying_inv

model_cfa_x2 <- '
  SocialSupport =~ social_support + teacher_student_relationship +
                  extra_inv + bullying_inv
'

fit_x2 <- cfa(
  model_cfa_x2,
  data = data_z,
  std.lv = TRUE,
  estimator = "MLR"
)

6.1 CFA X2 Summary

summary(fit_x2, fit.measures = TRUE, standardized = TRUE)
## lavaan 0.6-21 ended normally after 15 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                         8
## 
##   Number of observations                          1100
## 
## Model Test User Model:
##                                               Standard      Scaled
##   Test Statistic                                67.759      34.602
##   Degrees of freedom                                 2           2
##   P-value (Chi-square)                           0.000       0.000
##   Scaling correction factor                                  1.958
##     Yuan-Bentler correction (Mplus variant)                       
## 
## Model Test Baseline Model:
## 
##   Test statistic                              2074.587     877.586
##   Degrees of freedom                                 6           6
##   P-value                                        0.000       0.000
##   Scaling correction factor                                  2.364
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    0.968       0.963
##   Tucker-Lewis Index (TLI)                       0.905       0.888
##                                                                   
##   Robust Comparative Fit Index (CFI)                         0.969
##   Robust Tucker-Lewis Index (TLI)                            0.907
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -5237.914   -5237.914
##   Scaling correction factor                                  1.492
##       for the MLR correction                                      
##   Loglikelihood unrestricted model (H1)      -5204.035   -5204.035
##   Scaling correction factor                                  1.586
##       for the MLR correction                                      
##                                                                   
##   Akaike (AIC)                               10491.829   10491.829
##   Bayesian (BIC)                             10531.853   10531.853
##   Sample-size adjusted Bayesian (SABIC)      10506.443   10506.443
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.173       0.122
##   90 Percent confidence interval - lower         0.139       0.097
##   90 Percent confidence interval - upper         0.209       0.148
##   P-value H_0: RMSEA <= 0.050                    0.000       0.000
##   P-value H_0: RMSEA >= 0.080                    1.000       0.997
##                                                                   
##   Robust RMSEA                                               0.170
##   90 Percent confidence interval - lower                     0.123
##   90 Percent confidence interval - upper                     0.222
##   P-value H_0: Robust RMSEA <= 0.050                         0.000
##   P-value H_0: Robust RMSEA >= 0.080                         0.999
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.031       0.031
## 
## 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
##   SocialSupport =~                                                      
##     social_support    0.758    0.019   40.759    0.000    0.758    0.759
##     tchr_stdnt_rlt    0.837    0.023   36.284    0.000    0.837    0.838
##     extra_inv         0.735    0.026   28.384    0.000    0.735    0.735
##     bullying_inv      0.798    0.025   31.345    0.000    0.798    0.798
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .social_support    0.424    0.032   13.107    0.000    0.424    0.425
##    .tchr_stdnt_rlt    0.298    0.024   12.540    0.000    0.298    0.298
##    .extra_inv         0.459    0.042   10.862    0.000    0.459    0.460
##    .bullying_inv      0.363    0.042    8.591    0.000    0.363    0.363
##     SocialSupport     1.000                               1.000    1.000

6.2 CFA X2 Fit Indices

fi_x2 <- fitMeasures(fit_x2, c("chisq", "df", "pvalue", "cfi", "tli", "rmsea", "srmr"))
print(round(fi_x2, 4))
##  chisq     df pvalue    cfi    tli  rmsea   srmr 
## 67.759  2.000  0.000  0.968  0.905  0.173  0.031
cfi_x2   <- fitMeasures(fit_x2, "cfi")
tli_x2   <- fitMeasures(fit_x2, "tli")
rmsea_x2 <- fitMeasures(fit_x2, "rmsea")
srmr_x2  <- fitMeasures(fit_x2, "srmr")

eval_x2 <- data.frame(
  Index    = c("CFI", "TLI", "RMSEA", "SRMR"),
  Value    = round(c(cfi_x2, tli_x2, rmsea_x2, srmr_x2), 4),
  Target   = c("≥ 0.90", "≥ 0.90", "< 0.08", "< 0.08"),
  Status   = c(
    ifelse(cfi_x2   >= 0.90, "PASS", "FAIL"),
    ifelse(tli_x2   >= 0.90, "PASS", "FAIL"),
    ifelse(rmsea_x2 <  0.08, "PASS", "FAIL"),
    ifelse(srmr_x2  <  0.08, "PASS", "FAIL")
  )
)
print(eval_x2)
##       Index  Value Target Status
## cfi     CFI 0.9682 ≥ 0.90   PASS
## tli     TLI 0.9046 ≥ 0.90   PASS
## rmsea RMSEA 0.1729 < 0.08   FAIL
## srmr   SRMR 0.0314 < 0.08   PASS
Although the RMSEA value exceeded the recommended threshold, the model still demonstrated acceptable fit based on other indices such as CFI, TLI, and SRMR. The elevated RMSEA may be influenced by the small degrees of freedom (df = 2), which is known to inflate RMSEA values in simple CFA models.

6.3 CFA X2 Loading Factors

std_x2     <- standardizedSolution(fit_x2)
loading_x2 <- std_x2[std_x2$op == "=~", c("rhs", "est.std", "se", "pvalue")]
colnames(loading_x2) <- c("Indicator", "Std.Loading", "SE", "p-value")

loading_x2$Evaluation <- ifelse(
  abs(loading_x2$Std.Loading) >= 0.70, "Ideal (≥0.70)",
  ifelse(abs(loading_x2$Std.Loading) >= 0.50, "Acceptable (0.50–0.70)", "Weak (<0.50)")
)

loading_x2$Std.Loading <- round(loading_x2$Std.Loading, 4)
loading_x2$SE          <- round(loading_x2$SE, 4)
loading_x2$`p-value`   <- round(loading_x2$`p-value`, 4)

print(loading_x2[, 1:3])
##                      Indicator Std.Loading    SE
## 1               social_support       0.759 0.019
## 2 teacher_student_relationship       0.838 0.015
## 3                    extra_inv       0.735 0.026
## 4                 bullying_inv       0.798 0.025
cat("\n")
print(loading_x2[, c("Indicator", "Evaluation")])
##                      Indicator    Evaluation
## 1               social_support Ideal (≥0.70)
## 2 teacher_student_relationship Ideal (≥0.70)
## 3                    extra_inv Ideal (≥0.70)
## 4                 bullying_inv Ideal (≥0.70)

6.4 Composite Reliability and AVE X2

cr_ave_x2 <- calculate_CR_AVE(fit_x2)
alpha_x2  <- psych::alpha(data_z[, c(
  "social_support",
  "teacher_student_relationship",
  "extra_inv",
  "bullying_inv"
)])

rel_x2 <- data.frame(
  Measure = c("Composite Reliability (CR)", "AVE", "Cronbach's Alpha"),
  Value   = round(c(cr_ave_x2$CR, cr_ave_x2$AVE, alpha_x2$total$raw_alpha), 4),
  Target  = c("≥ 0.70", "≥ 0.50", "≥ 0.70"),
  Status  = c(
    ifelse(cr_ave_x2$CR              >= 0.70, "PASS", "FAIL"),
    ifelse(cr_ave_x2$AVE             >= 0.50, "PASS", "FAIL"),
    ifelse(alpha_x2$total$raw_alpha  >= 0.70, "PASS", "FAIL")
  )
)
print(rel_x2)
##                      Measure  Value Target Status
## 1 Composite Reliability (CR) 0.8637 ≥ 0.70   PASS
## 2                        AVE 0.6137 ≥ 0.50   PASS
## 3           Cronbach's Alpha 0.8629 ≥ 0.70   PASS

6.5 CFA X2 Path Diagram

semPaths(
  object         = fit_x2,
  what           = "path",
  whatLabels     = "std",
  style          = "ram",
  layout         = "tree",
  rotation       = 2,
  sizeMan        = 7,
  sizeLat        = 8,
  edge.label.cex = 1.2,
  label.cex      = 1.1,
  color          = list(lat = "#F9E79F", man = "#FDEBD0"),
  mar            = c(3, 3, 3, 3)
)
title(main = "CFA — Social Support (X2)", cex.main = 1.3, font.main = 2)

7 CFA — Psychological Well-Being (Y)

model_cfa_y <- '
  PsychologicalWellBeing =~ self_esteem +
                             depression_inv +
                             sleep_quality +
                             mental_health_history_inv
'

fit_y <- cfa(
  model_cfa_y,
  data = data_z,
  std.lv = TRUE,
  estimator = "MLR"
)

7.1 CFA Y Summary

summary(fit_y, fit.measures = TRUE, standardized = TRUE)
## lavaan 0.6-21 ended normally after 17 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                         8
## 
##   Number of observations                          1100
## 
## Model Test User Model:
##                                               Standard      Scaled
##   Test Statistic                                 2.464       1.181
##   Degrees of freedom                                 2           2
##   P-value (Chi-square)                           0.292       0.554
##   Scaling correction factor                                  2.086
##     Yuan-Bentler correction (Mplus variant)                       
## 
## Model Test Baseline Model:
## 
##   Test statistic                              2303.929    1108.938
##   Degrees of freedom                                 6           6
##   P-value                                        0.000       0.000
##   Scaling correction factor                                  2.078
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    1.000       1.000
##   Tucker-Lewis Index (TLI)                       0.999       1.002
##                                                                   
##   Robust Comparative Fit Index (CFI)                         1.000
##   Robust Tucker-Lewis Index (TLI)                            1.002
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -5090.597   -5090.597
##   Scaling correction factor                                  1.201
##       for the MLR correction                                      
##   Loglikelihood unrestricted model (H1)      -5089.364   -5089.364
##   Scaling correction factor                                  1.378
##       for the MLR correction                                      
##                                                                   
##   Akaike (AIC)                               10197.193   10197.193
##   Bayesian (BIC)                             10237.218   10237.218
##   Sample-size adjusted Bayesian (SABIC)      10211.808   10211.808
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.015       0.000
##   90 Percent confidence interval - lower         0.000       0.000
##   90 Percent confidence interval - upper         0.063       0.035
##   P-value H_0: RMSEA <= 0.050                    0.853       0.994
##   P-value H_0: RMSEA >= 0.080                    0.008       0.000
##                                                                   
##   Robust RMSEA                                               0.000
##   90 Percent confidence interval - lower                     0.000
##   90 Percent confidence interval - upper                     0.074
##   P-value H_0: Robust RMSEA <= 0.050                         0.833
##   P-value H_0: Robust RMSEA >= 0.080                         0.034
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.005       0.005
## 
## Parameter Estimates:
## 
##   Standard errors                             Sandwich
##   Information bread                           Observed
##   Observed information based on                Hessian
## 
## Latent Variables:
##                             Estimate  Std.Err  z-value  P(>|z|)   Std.lv
##   PsychologicalWellBeing =~                                             
##     self_esteem                0.818    0.021   39.909    0.000    0.818
##     depression_inv             0.847    0.021   41.157    0.000    0.847
##     sleep_quality              0.818    0.020   41.878    0.000    0.818
##     mntl_hlth_hst_             0.737    0.016   47.078    0.000    0.737
##   Std.all
##          
##     0.819
##     0.847
##     0.818
##     0.737
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .self_esteem       0.329    0.027   12.276    0.000    0.329    0.330
##    .depression_inv    0.282    0.027   10.569    0.000    0.282    0.282
##    .sleep_quality     0.330    0.030   11.009    0.000    0.330    0.331
##    .mntl_hlth_hst_    0.456    0.023   19.775    0.000    0.456    0.456
##     PsychlgclWllBn    1.000                               1.000    1.000

7.2 CFA Y Fit Indices

fi_y <- fitMeasures(
  fit_y,
  c("chisq", "df", "pvalue", "cfi", "tli", "rmsea", "srmr")
)

print(round(fi_y, 4))
##  chisq     df pvalue    cfi    tli  rmsea   srmr 
##  2.465  2.000  0.292  1.000  0.999  0.015  0.005
cfi_y   <- fitMeasures(fit_y, "cfi")
tli_y   <- fitMeasures(fit_y, "tli")
rmsea_y <- fitMeasures(fit_y, "rmsea")
srmr_y  <- fitMeasures(fit_y, "srmr")

eval_y <- data.frame(
  Index  = c("CFI", "TLI", "RMSEA", "SRMR"),
  Value  = round(c(cfi_y, tli_y, rmsea_y, srmr_y), 4),
  Target = c("≥ 0.90", "≥ 0.90", "< 0.08", "< 0.08"),
  Status = c(
    ifelse(cfi_y   >= 0.90, "PASS", "FAIL"),
    ifelse(tli_y   >= 0.90, "PASS", "FAIL"),
    ifelse(rmsea_y <  0.08, "PASS", "FAIL"),
    ifelse(srmr_y  <  0.08, "PASS", "FAIL")
  )
)

print(eval_y)
##       Index  Value Target Status
## cfi     CFI 0.9998 ≥ 0.90   PASS
## tli     TLI 0.9994 ≥ 0.90   PASS
## rmsea RMSEA 0.0145 < 0.08   PASS
## srmr   SRMR 0.0053 < 0.08   PASS
Although the RMSEA value may be slightly high, the model can still be considered acceptable if supported by strong CFI, TLI, and SRMR values. Small degrees of freedom may inflate RMSEA values in simple CFA models.

7.3 CFA Y Loading Factors

std_y <- standardizedSolution(fit_y)

loading_y <- std_y[
  std_y$op == "=~",
  c("rhs", "est.std", "se", "pvalue")
]

colnames(loading_y) <- c(
  "Indicator",
  "Std.Loading",
  "SE",
  "p-value"
)

loading_y$Evaluation <- ifelse(
  abs(loading_y$Std.Loading) >= 0.70,
  "Ideal (≥0.70)",
  ifelse(
    abs(loading_y$Std.Loading) >= 0.50,
    "Acceptable (0.50–0.70)",
    "Weak (<0.50)"
  )
)

loading_y$Std.Loading <- round(loading_y$Std.Loading, 4)
loading_y$SE          <- round(loading_y$SE, 4)
loading_y$`p-value`   <- round(loading_y$`p-value`, 4)

print(loading_y[, 1:3])
##                   Indicator Std.Loading    SE
## 1               self_esteem       0.819 0.016
## 2            depression_inv       0.847 0.015
## 3             sleep_quality       0.818 0.017
## 4 mental_health_history_inv       0.737 0.016
cat("\n")
print(loading_y[, c("Indicator", "Evaluation")])
##                   Indicator    Evaluation
## 1               self_esteem Ideal (≥0.70)
## 2            depression_inv Ideal (≥0.70)
## 3             sleep_quality Ideal (≥0.70)
## 4 mental_health_history_inv Ideal (≥0.70)

7.4 Composite Reliability and AVE Y

cr_ave_y <- calculate_CR_AVE(fit_y)

alpha_y <- psych::alpha(data_z[, c(
  "self_esteem",
  "depression_inv",
  "sleep_quality",
  "mental_health_history_inv"
)])

rel_y <- data.frame(
  Measure = c(
    "Composite Reliability (CR)",
    "AVE",
    "Cronbach's Alpha"
  ),
  Value = round(c(
    cr_ave_y$CR,
    cr_ave_y$AVE,
    alpha_y$total$raw_alpha
  ), 4),
  Target = c("≥ 0.70", "≥ 0.50", "≥ 0.70"),
  Status = c(
    ifelse(cr_ave_y$CR             >= 0.70, "PASS", "FAIL"),
    ifelse(cr_ave_y$AVE            >= 0.50, "PASS", "FAIL"),
    ifelse(alpha_y$total$raw_alpha >= 0.70, "PASS", "FAIL")
  )
)

print(rel_y)
##                      Measure  Value Target Status
## 1 Composite Reliability (CR) 0.8812 ≥ 0.70   PASS
## 2                        AVE 0.6503 ≥ 0.50   PASS
## 3           Cronbach's Alpha 0.8805 ≥ 0.70   PASS

7.5 CFA Y Path Diagram

semPaths(
  object         = fit_y,
  what           = "path",
  whatLabels     = "std",
  style          = "ram",
  layout         = "tree",
  rotation       = 2,
  sizeMan        = 7,
  sizeLat        = 8,
  edge.label.cex = 1.2,
  label.cex      = 1.1,
  color          = list(
    lat = "#D7BDE2",
    man = "#F5EEF8"
  ),
  mar = c(3, 3, 3, 3)
)

title(
  main = "CFA — Psychological Well-Being (Y)",
  cex.main = 1.3,
  font.main = 2
)

8 Measurement Model

8.1 Full Measurement Model

measurement_model <- '
  # Latent Variables
  AcademicStress =~ anxiety_level +
                     study_load +
                     academic_performance_inv +
                     future_career_concerns +
                     peer_pressure

  SocialSupport =~ social_support +
                    teacher_student_relationship +
                    extra_inv +
                    bullying_inv
  
  PsychologicalWellBeing =~ self_esteem +
                             depression_inv +
                             sleep_quality +
                             mental_health_history_inv
'

fit_measurement <- cfa(
  measurement_model,
  data   = data_z,
  std.lv = TRUE,
  estimator = "MLR"
)

8.2 Measurement Model Summary

summary(
  fit_measurement,
  fit.measures = TRUE,
  standardized = TRUE
)
## lavaan 0.6-21 ended normally after 28 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        29
## 
##   Number of observations                          1100
## 
## Model Test User Model:
##                                               Standard      Scaled
##   Test Statistic                               340.122     136.554
##   Degrees of freedom                                62          62
##   P-value (Chi-square)                           0.000       0.000
##   Scaling correction factor                                  2.491
##     Yuan-Bentler correction (Mplus variant)                       
## 
## Model Test Baseline Model:
## 
##   Test statistic                             11173.583    4608.024
##   Degrees of freedom                                78          78
##   P-value                                        0.000       0.000
##   Scaling correction factor                                  2.425
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    0.975       0.984
##   Tucker-Lewis Index (TLI)                       0.968       0.979
##                                                                   
##   Robust Comparative Fit Index (CFI)                         0.983
##   Robust Tucker-Lewis Index (TLI)                            0.979
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)             -14867.588  -14867.588
##   Scaling correction factor                                  1.384
##       for the MLR correction                                      
##   Loglikelihood unrestricted model (H1)     -14697.527  -14697.527
##   Scaling correction factor                                  2.138
##       for the MLR correction                                      
##                                                                   
##   Akaike (AIC)                               29793.176   29793.176
##   Bayesian (BIC)                             29938.265   29938.265
##   Sample-size adjusted Bayesian (SABIC)      29846.154   29846.154
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.064       0.033
##   90 Percent confidence interval - lower         0.057       0.028
##   90 Percent confidence interval - upper         0.071       0.038
##   P-value H_0: RMSEA <= 0.050                    0.000       1.000
##   P-value H_0: RMSEA >= 0.080                    0.000       0.000
##                                                                   
##   Robust RMSEA                                               0.052
##   90 Percent confidence interval - lower                     0.040
##   90 Percent confidence interval - upper                     0.064
##   P-value H_0: Robust RMSEA <= 0.050                         0.365
##   P-value H_0: Robust RMSEA >= 0.080                         0.000
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.023       0.023
## 
## Parameter Estimates:
## 
##   Standard errors                             Sandwich
##   Information bread                           Observed
##   Observed information based on                Hessian
## 
## Latent Variables:
##                             Estimate  Std.Err  z-value  P(>|z|)   Std.lv
##   AcademicStress =~                                                     
##     anxiety_level              0.836    0.018   47.515    0.000    0.836
##     study_load                 0.689    0.020   34.406    0.000    0.689
##     acdmc_prfrmnc_             0.780    0.018   44.429    0.000    0.780
##     ftr_crr_cncrns             0.846    0.016   54.216    0.000    0.846
##     peer_pressure              0.763    0.018   41.685    0.000    0.763
##   SocialSupport =~                                                      
##     social_support             0.717    0.013   53.602    0.000    0.717
##     tchr_stdnt_rlt             0.804    0.018   43.483    0.000    0.804
##     extra_inv                  0.769    0.018   43.863    0.000    0.769
##     bullying_inv               0.831    0.016   52.328    0.000    0.831
##   PsychologicalWellBeing =~                                             
##     self_esteem                0.820    0.018   46.838    0.000    0.820
##     depression_inv             0.834    0.018   46.240    0.000    0.834
##     sleep_quality              0.827    0.016   53.344    0.000    0.827
##     mntl_hlth_hst_             0.741    0.012   61.332    0.000    0.741
##   Std.all
##          
##     0.836
##     0.689
##     0.780
##     0.846
##     0.763
##          
##     0.717
##     0.804
##     0.769
##     0.832
##          
##     0.820
##     0.834
##     0.827
##     0.741
## 
## Covariances:
##                     Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   AcademicStress ~~                                                      
##     SocialSupport     -1.003    0.011  -90.052    0.000   -1.003   -1.003
##     PsychlgclWllBn    -1.005    0.009 -105.878    0.000   -1.005   -1.005
##   SocialSupport ~~                                                       
##     PsychlgclWllBn     0.995    0.011   93.449    0.000    0.995    0.995
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .anxiety_level     0.301    0.020   15.220    0.000    0.301    0.301
##    .study_load        0.525    0.030   17.462    0.000    0.525    0.525
##    .acdmc_prfrmnc_    0.391    0.024   16.362    0.000    0.391    0.391
##    .ftr_crr_cncrns    0.284    0.023   12.305    0.000    0.284    0.284
##    .peer_pressure     0.417    0.028   14.794    0.000    0.417    0.418
##    .social_support    0.485    0.029   16.659    0.000    0.485    0.486
##    .tchr_stdnt_rlt    0.353    0.022   16.294    0.000    0.353    0.354
##    .extra_inv         0.408    0.028   14.632    0.000    0.408    0.408
##    .bullying_inv      0.308    0.025   12.518    0.000    0.308    0.308
##    .self_esteem       0.327    0.021   15.799    0.000    0.327    0.327
##    .depression_inv    0.304    0.020   15.199    0.000    0.304    0.304
##    .sleep_quality     0.315    0.023   13.447    0.000    0.315    0.316
##    .mntl_hlth_hst_    0.450    0.018   25.167    0.000    0.450    0.451
##     AcademicStress    1.000                               1.000    1.000
##     SocialSupport     1.000                               1.000    1.000
##     PsychlgclWllBn    1.000                               1.000    1.000
lavInspect(fit_measurement, "cor.lv")
##                        AcdmcS SclSpp PsycWB
## AcademicStress          1.000              
## SocialSupport          -1.003  1.000       
## PsychologicalWellBeing -1.005  0.995  1.000

8.3 Measurement Model Fit Indices

fit_indices_measurement <- fitMeasures(
  fit_measurement,
  c(
    "chisq",
    "df",
    "pvalue",
    "cfi",
    "tli",
    "rmsea",
    "srmr"
  )
)

print(round(fit_indices_measurement, 4))
##   chisq      df  pvalue     cfi     tli   rmsea    srmr 
## 340.122  62.000   0.000   0.975   0.969   0.064   0.023

9 Structural Model (SEM)

9.1 SEM Model

model_sem <- '
  # Measurement Model
  AcademicStress =~ anxiety_level +
                     study_load +
                     academic_performance_inv +
                     future_career_concerns +
                     peer_pressure

  SocialSupport =~ social_support +
                    teacher_student_relationship +
                    extra_inv +
                    bullying_inv

  PsychologicalWellBeing =~ self_esteem +
                             depression_inv +
                             sleep_quality +
                             mental_health_history_inv

  # Structural Model
  PsychologicalWellBeing ~ AcademicStress + SocialSupport
'

fit_sem <- sem(
  model_sem,
  data   = data_z,
  std.lv = TRUE,
  estimator = "MLR"
)
inspect(fit_sem, "converged")
## [1] FALSE

9.2 SEM Summary

summary(
  fit_sem,
  fit.measures = TRUE,
  standardized = TRUE,
  rsquare = TRUE
)
## lavaan 0.6-21 did NOT end normally after 2304 iterations
## ** WARNING ** Estimates below are most likely unreliable
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        29
## 
##   Number of observations                          1100
## 
## 
## Parameter Estimates:
## 
##   Standard errors                             Sandwich
##   Information bread                           Observed
##   Observed information based on                Hessian
## 
## Latent Variables:
##                             Estimate    Std.Err  z-value  P(>|z|)   Std.lv
##   AcademicStress =~                                                       
##     anxiety_level                0.837       NA                      0.837
##     study_load                   0.689       NA                      0.689
##     acdmc_prfrmnc_               0.780       NA                      0.780
##     ftr_crr_cncrns               0.847       NA                      0.847
##     peer_pressure                0.764       NA                      0.764
##   SocialSupport =~                                                        
##     social_support               0.715       NA                      0.715
##     tchr_stdnt_rlt               0.801       NA                      0.801
##     extra_inv                    0.768       NA                      0.768
##     bullying_inv                 0.829       NA                      0.829
##   PsychologicalWellBeing =~                                               
##     self_esteem                  0.000       NA                      0.820
##     depression_inv               0.000       NA                      0.834
##     sleep_quality                0.000       NA                      0.827
##     mntl_hlth_hst_               0.000       NA                      0.740
##   Std.all
##          
##     0.837
##     0.690
##     0.781
##     0.847
##     0.764
##          
##     0.715
##     0.802
##     0.768
##     0.829
##          
##     0.821
##     0.834
##     0.827
##     0.741
## 
## Regressions:
##                            Estimate    Std.Err  z-value  P(>|z|)   Std.lv
##   PsychologicalWellBeing ~                                               
##     AcademicStress         -13587.695       NA                     -0.445
##     SocialSupport           16920.625       NA                      0.554
##   Std.all
##          
##    -0.445
##     0.554
## 
## Covariances:
##                     Estimate    Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   AcademicStress ~~                                                        
##     SocialSupport       -1.004       NA                     -1.004   -1.004
## 
## Variances:
##                    Estimate    Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .anxiety_level       0.299       NA                      0.299    0.299
##    .study_load          0.524       NA                      0.524    0.524
##    .acdmc_prfrmnc_      0.390       NA                      0.390    0.390
##    .ftr_crr_cncrns      0.282       NA                      0.282    0.282
##    .peer_pressure       0.416       NA                      0.416    0.416
##    .social_support      0.488       NA                      0.488    0.489
##    .tchr_stdnt_rlt      0.357       NA                      0.357    0.357
##    .extra_inv           0.410       NA                      0.410    0.410
##    .bullying_inv        0.312       NA                      0.312    0.312
##    .self_esteem         0.326       NA                      0.326    0.327
##    .depression_inv      0.304       NA                      0.304    0.304
##    .sleep_quality       0.316       NA                      0.316    0.316
##    .mntl_hlth_hst_      0.451       NA                      0.451    0.451
##     AcademicStress      1.000                               1.000    1.000
##     SocialSupport       1.000                               1.000    1.000
##    .PsychlgclWllBn      1.000                               0.000    0.000
## 
## R-Square:
##                    Estimate  
##     anxiety_level       0.701
##     study_load          0.476
##     acdmc_prfrmnc_      0.610
##     ftr_crr_cncrns      0.718
##     peer_pressure       0.584
##     social_support      0.511
##     tchr_stdnt_rlt      0.643
##     extra_inv           0.590
##     bullying_inv        0.688
##     self_esteem         0.673
##     depression_inv      0.696
##     sleep_quality       0.684
##     mntl_hlth_hst_      0.549
##     PsychlgclWllBn      1.000

9.3 SEM Goodness of Fit

if(inspect(fit_sem, "converged")) {

  fit_sem_indices <- fitMeasures(
    fit_sem,
    c(
      "chisq",
      "df",
      "pvalue",
      "cfi",
      "tli",
      "rmsea",
      "srmr"
    )
  )

  print(round(fit_sem_indices, 4))

  cfi_sem   <- fitMeasures(fit_sem, "cfi")
  tli_sem   <- fitMeasures(fit_sem, "tli")
  rmsea_sem <- fitMeasures(fit_sem, "rmsea")
  srmr_sem  <- fitMeasures(fit_sem, "srmr")

  eval_sem <- data.frame(
    Index  = c("CFI", "TLI", "RMSEA", "SRMR"),
    Value  = round(c(cfi_sem, tli_sem, rmsea_sem, srmr_sem), 4),
    Target = c("≥ 0.90", "≥ 0.90", "< 0.08", "< 0.08"),
    Status = c(
      ifelse(cfi_sem   >= 0.90, "PASS", "FAIL"),
      ifelse(tli_sem   >= 0.90, "PASS", "FAIL"),
      ifelse(rmsea_sem <  0.08, "PASS", "FAIL"),
      ifelse(srmr_sem  <  0.08, "PASS", "FAIL")
    )
  )

  print(eval_sem)

} else {

  cat("SEM model did not converge.\n")
  cat("Fit indices cannot be calculated.\n")
  cat("Possible causes:\n")
  cat("- Multicollinearity between latent variables\n")
  cat("- Correlation between constructs too high\n")
  cat("- Model misspecification\n")

}
## SEM model did not converge.
## Fit indices cannot be calculated.
## Possible causes:
## - Multicollinearity between latent variables
## - Correlation between constructs too high
## - Model misspecification

9.4 Hypothesis Testing

sem_paths <- standardizedSolution(fit_sem)

hypothesis_result <- sem_paths[
  sem_paths$op == "~",
  c("lhs", "rhs", "est.std", "z", "pvalue")
]

colnames(hypothesis_result) <- c(
  "Dependent",
  "Independent",
  "Std.Estimate",
  "Z-value",
  "p-value"
)

hypothesis_result$Decision <- ifelse(
  hypothesis_result$`p-value` < 0.05,
  "Significant",
  "Not Significant"
)

hypothesis_result$Std.Estimate <- round(
  hypothesis_result$Std.Estimate,
  4
)

hypothesis_result$`Z-value` <- round(
  hypothesis_result$`Z-value`,
  4
)

hypothesis_result$`p-value` <- round(
  hypothesis_result$`p-value`,
  4
)

print(hypothesis_result)
##                 Dependent    Independent Std.Estimate Z.value p.value Decision
## 14 PsychologicalWellBeing AcademicStress       -0.445      NA      NA       NA
## 15 PsychologicalWellBeing  SocialSupport        0.554      NA      NA       NA

9.5 R-Square

r2 <- inspect(fit_sem, "r2")

print(round(r2, 4))
##                anxiety_level                   study_load 
##                        0.701                        0.476 
##     academic_performance_inv       future_career_concerns 
##                        0.610                        0.718 
##                peer_pressure               social_support 
##                        0.584                        0.511 
## teacher_student_relationship                    extra_inv 
##                        0.643                        0.590 
##                 bullying_inv                  self_esteem 
##                        0.688                        0.673 
##               depression_inv                sleep_quality 
##                        0.696                        0.684 
##    mental_health_history_inv       PsychologicalWellBeing 
##                        0.549                        1.000

9.6 SEM Path Diagram

semPaths(
  object         = fit_sem,
  what           = "std",
  whatLabels     = "std",
  style          = "ram",
  layout         = "tree",
  rotation       = 2,
  sizeLat        = 9,
  sizeMan        = 6,
  edge.label.cex = 1.1,
  label.cex      = 1,
  residuals      = FALSE,
  intercepts     = FALSE,
  mar            = c(4, 4, 4, 4),
  color = list(
    lat = "#85C1E9",
    man = "#D5F5E3"
  )
)

title(
  main = "Structural Equation Modeling (SEM)",
  cex.main = 1.4,
  font.main = 2
)

9.7 Interpretation of Hypothesis

cat("Interpretation of Structural Relationships\n\n")
## Interpretation of Structural Relationships
# Academic Stress - Psychological Well-Being
p1 <- hypothesis_result$`p-value`[1]

if(!is.na(p1) && p1 < 0.05){
  cat(
    "Academic Stress significantly influences Psychological Well-Being.\n"
  )
} else {
  cat(
    "Academic Stress does not significantly influence Psychological Well-Being.\n"
  )
}
## Academic Stress does not significantly influence Psychological Well-Being.
# Social Support - Psychological Well-Being
p2 <- hypothesis_result$`p-value`[2]

if(!is.na(p2) && p2 < 0.05){
  cat(
    "Social Support significantly influences Psychological Well-Being.\n"
  )
} else {
  cat(
    "Social Support does not significantly influence Psychological Well-Being.\n"
  )
}
## Social Support does not significantly influence Psychological Well-Being.
The convergence issue in the full SEM model cannot be resolved simply by modifying the code or estimation method. Therefore, in addition to using the full SEM model, this study also explores an alternative approach by splitting the analysis into two separate structural models, namely H1 and H2. This approach was adopted to determine whether the convergence problem was caused by the simultaneous use of multiple latent constructs within a single SEM model.

10 Structural Model H1

10.1 Academic Stress - Psychological Well-Being

model_h1 <- '
  AcademicStress =~ anxiety_level +
                     study_load +
                     academic_performance_inv +
                     future_career_concerns +
                     peer_pressure

  PsychologicalWellBeing =~ self_esteem +
                             depression_inv +
                             sleep_quality +
                             mental_health_history_inv

  PsychologicalWellBeing ~ AcademicStress
'

fit_h1 <- sem(
  model_h1,
  data = data_z,
  std.lv = TRUE,
  estimator = "MLR"
)

inspect(fit_h1, "converged")
## [1] FALSE

10.2 H1 Summary

summary(
  fit_h1,
  fit.measures = TRUE,
  standardized = TRUE,
  rsquare = TRUE
)
## lavaan 0.6-21 did NOT end normally after 1384 iterations
## ** WARNING ** Estimates below are most likely unreliable
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        19
## 
##   Number of observations                          1100
## 
## 
## Parameter Estimates:
## 
##   Standard errors                             Sandwich
##   Information bread                           Observed
##   Observed information based on                Hessian
## 
## Latent Variables:
##                             Estimate   Std.Err  z-value  P(>|z|)   Std.lv
##   AcademicStress =~                                                      
##     anxiety_level               0.841       NA                      0.841
##     study_load                  0.694       NA                      0.694
##     acdmc_prfrmnc_              0.771       NA                      0.771
##     ftr_crr_cncrns              0.846       NA                      0.846
##     peer_pressure               0.766       NA                      0.766
##   PsychologicalWellBeing =~                                              
##     self_esteem                 0.001       NA                      0.817
##     depression_inv              0.001       NA                      0.835
##     sleep_quality               0.001       NA                      0.828
##     mntl_hlth_hst_              0.001       NA                      0.746
##   Std.all
##          
##     0.841
##     0.695
##     0.771
##     0.847
##     0.766
##          
##     0.818
##     0.836
##     0.828
##     0.747
## 
## Regressions:
##                            Estimate   Std.Err  z-value  P(>|z|)   Std.lv
##   PsychologicalWellBeing ~                                              
##     AcademicStress         -1150.603       NA                     -1.000
##   Std.all
##          
##    -1.000
## 
## Variances:
##                    Estimate   Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .anxiety_level      0.292       NA                      0.292    0.292
##    .study_load         0.517       NA                      0.517    0.517
##    .acdmc_prfrmnc_     0.405       NA                      0.405    0.406
##    .ftr_crr_cncrns     0.283       NA                      0.283    0.283
##    .peer_pressure      0.412       NA                      0.412    0.413
##    .self_esteem        0.331       NA                      0.331    0.331
##    .depression_inv     0.301       NA                      0.301    0.302
##    .sleep_quality      0.314       NA                      0.314    0.314
##    .mntl_hlth_hst_     0.442       NA                      0.442    0.442
##     AcademicStress     1.000                               1.000    1.000
##    .PsychlgclWllBn     1.000                               0.000    0.000
## 
## R-Square:
##                    Estimate 
##     anxiety_level      0.708
##     study_load         0.483
##     acdmc_prfrmnc_     0.594
##     ftr_crr_cncrns     0.717
##     peer_pressure      0.587
##     self_esteem        0.669
##     depression_inv     0.698
##     sleep_quality      0.686
##     mntl_hlth_hst_     0.558
##     PsychlgclWllBn     1.000

10.3 H1 Fit Indices

if(inspect(fit_h1, "converged")) {

  fit_h1_indices <- fitMeasures(
    fit_h1,
    c(
      "chisq",
      "df",
      "pvalue",
      "cfi",
      "tli",
      "rmsea",
      "srmr"
    )
  )

  print(round(fit_h1_indices, 4))

} else {

  cat("H1 model did not converge.\n")
  cat("Fit indices cannot be calculated.\n")

}
## H1 model did not converge.
## Fit indices cannot be calculated.

10.4 H1 Hypothesis Test

h1_paths <- standardizedSolution(fit_h1)

h1_result <- h1_paths[
  h1_paths$op == "~",
  c("lhs", "rhs", "est.std", "z", "pvalue")
]

colnames(h1_result) <- c(
  "Dependent",
  "Independent",
  "Std.Estimate",
  "Z-value",
  "p-value"
)

h1_result$Decision <- ifelse(
  h1_result$`p-value` < 0.05,
  "Significant",
  "Not Significant"
)

h1_result$Std.Estimate <- round(h1_result$Std.Estimate, 4)
h1_result$`Z-value` <- round(h1_result$`Z-value`, 4)
h1_result$`p-value` <- round(h1_result$`p-value`, 4)

print(h1_result)
##                 Dependent    Independent Std.Estimate Z.value p.value Decision
## 10 PsychologicalWellBeing AcademicStress           -1      NA      NA       NA

10.5 H1 R-Square

r2_h1 <- inspect(fit_h1, "r2")

print(round(r2_h1, 4))
##             anxiety_level                study_load  academic_performance_inv 
##                     0.708                     0.483                     0.594 
##    future_career_concerns             peer_pressure               self_esteem 
##                     0.717                     0.588                     0.669 
##            depression_inv             sleep_quality mental_health_history_inv 
##                     0.698                     0.686                     0.558 
##    PsychologicalWellBeing 
##                     1.000

10.6 H1 Path Diagram

semPaths(
  object         = fit_h1,
  what           = "std",
  whatLabels     = "std",
  style          = "ram",
  layout         = "tree",
  rotation       = 2,
  sizeLat        = 9,
  sizeMan        = 6,
  edge.label.cex = 1.1,
  label.cex      = 1,
  residuals      = FALSE,
  intercepts     = FALSE,
  mar            = c(4, 4, 4, 4),
  color = list(
    lat = "#85C1E9",
    man = "#D5F5E3"
  )
)

title(
  main = "H1: Academic Stress - Psychological Well-Being",
  cex.main = 1.3,
  font.main = 2
)

11 Structural Model H2

11.1 Social Support - Psychological Well-Being

model_h2 <- '
  SocialSupport =~ social_support +
                    teacher_student_relationship +
                    extra_inv +
                    bullying_inv

  PsychologicalWellBeing =~ self_esteem +
                             depression_inv +
                             sleep_quality +
                             mental_health_history_inv

  PsychologicalWellBeing ~ SocialSupport
'

fit_h2 <- sem(
  model_h2,
  data = data_z,
  std.lv = TRUE,
  estimator = "MLR"
)

inspect(fit_h2, "converged")
## [1] TRUE

11.2 H2 Summary

summary(
  fit_h2,
  fit.measures = TRUE,
  standardized = TRUE,
  rsquare = TRUE
)
## lavaan 0.6-21 ended normally after 74 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        17
## 
##   Number of observations                          1100
## 
## Model Test User Model:
##                                               Standard      Scaled
##   Test Statistic                               195.218      84.289
##   Degrees of freedom                                19          19
##   P-value (Chi-square)                           0.000       0.000
##   Scaling correction factor                                  2.316
##     Yuan-Bentler correction (Mplus variant)                       
## 
## Model Test Baseline Model:
## 
##   Test statistic                              6071.858    2695.830
##   Degrees of freedom                                28          28
##   P-value                                        0.000       0.000
##   Scaling correction factor                                  2.252
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    0.971       0.976
##   Tucker-Lewis Index (TLI)                       0.957       0.964
##                                                                   
##   Robust Comparative Fit Index (CFI)                         0.975
##   Robust Tucker-Lewis Index (TLI)                            0.963
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -9544.337   -9544.337
##   Scaling correction factor                                  1.297
##       for the MLR correction                                      
##   Loglikelihood unrestricted model (H1)      -9446.728   -9446.728
##   Scaling correction factor                                  1.835
##       for the MLR correction                                      
##                                                                   
##   Akaike (AIC)                               19122.674   19122.674
##   Bayesian (BIC)                             19207.726   19207.726
##   Sample-size adjusted Bayesian (SABIC)      19153.730   19153.730
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.092       0.056
##   90 Percent confidence interval - lower         0.080       0.048
##   90 Percent confidence interval - upper         0.104       0.064
##   P-value H_0: RMSEA <= 0.050                    0.000       0.107
##   P-value H_0: RMSEA >= 0.080                    0.955       0.000
##                                                                   
##   Robust RMSEA                                               0.085
##   90 Percent confidence interval - lower                     0.067
##   90 Percent confidence interval - upper                     0.104
##   P-value H_0: Robust RMSEA <= 0.050                         0.001
##   P-value H_0: Robust RMSEA >= 0.080                         0.693
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.027       0.027
## 
## Parameter Estimates:
## 
##   Standard errors                             Sandwich
##   Information bread                           Observed
##   Observed information based on                Hessian
## 
## Latent Variables:
##                             Estimate  Std.Err  z-value  P(>|z|)   Std.lv
##   SocialSupport =~                                                      
##     social_support             0.741    0.013   55.829    0.000    0.741
##     tchr_stdnt_rlt             0.814    0.019   43.501    0.000    0.814
##     extra_inv                  0.761    0.019   39.908    0.000    0.761
##     bullying_inv               0.814    0.018   45.282    0.000    0.814
##   PsychologicalWellBeing =~                                             
##     self_esteem                0.080    0.090    0.894    0.371    0.826
##     depression_inv             0.081    0.091    0.893    0.372    0.839
##     sleep_quality              0.080    0.089    0.893    0.372    0.822
##     mntl_hlth_hst_             0.071    0.079    0.894    0.371    0.732
##   Std.all
##          
##     0.741
##     0.815
##     0.761
##     0.814
##          
##     0.826
##     0.839
##     0.823
##     0.732
## 
## Regressions:
##                            Estimate  Std.Err  z-value  P(>|z|)   Std.lv
##   PsychologicalWellBeing ~                                             
##     SocialSupport            10.253   11.557    0.887    0.375    0.995
##   Std.all
##          
##     0.995
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .social_support    0.451    0.028   15.836    0.000    0.451    0.451
##    .tchr_stdnt_rlt    0.336    0.020   16.486    0.000    0.336    0.336
##    .extra_inv         0.420    0.031   13.524    0.000    0.420    0.420
##    .bullying_inv      0.337    0.029   11.828    0.000    0.337    0.338
##    .self_esteem       0.317    0.021   14.862    0.000    0.317    0.317
##    .depression_inv    0.296    0.022   13.354    0.000    0.296    0.296
##    .sleep_quality     0.323    0.025   12.708    0.000    0.323    0.323
##    .mntl_hlth_hst_    0.464    0.020   22.655    0.000    0.464    0.464
##     SocialSupport     1.000                               1.000    1.000
##    .PsychlgclWllBn    1.000                               0.009    0.009
## 
## R-Square:
##                    Estimate
##     social_support    0.549
##     tchr_stdnt_rlt    0.664
##     extra_inv         0.580
##     bullying_inv      0.662
##     self_esteem       0.683
##     depression_inv    0.704
##     sleep_quality     0.677
##     mntl_hlth_hst_    0.536
##     PsychlgclWllBn    0.991

11.3 H2 Fit Indices

fit_h2_indices <- fitMeasures(
  fit_h2,
  c(
    "chisq",
    "df",
    "pvalue",
    "cfi",
    "tli",
    "rmsea",
    "srmr"
  )
)

print(round(fit_h2_indices, 4))
##   chisq      df  pvalue     cfi     tli   rmsea    srmr 
## 195.218  19.000   0.000   0.971   0.957   0.092   0.027

11.4 H2 Hypothesis Test

h2_paths <- standardizedSolution(fit_h2)

h2_result <- h2_paths[
  h2_paths$op == "~",
  c("lhs", "rhs", "est.std", "z", "pvalue")
]

colnames(h2_result) <- c(
  "Dependent",
  "Independent",
  "Std.Estimate",
  "Z-value",
  "p-value"
)

h2_result$Decision <- ifelse(
  h2_result$`p-value` < 0.05,
  "Significant",
  "Not Significant"
)

h2_result$Std.Estimate <- round(h2_result$Std.Estimate, 4)
h2_result$`Z-value` <- round(h2_result$`Z-value`, 4)
h2_result$`p-value` <- round(h2_result$`p-value`, 4)

print(h2_result)
##                Dependent   Independent Std.Estimate Z.value p.value    Decision
## 9 PsychologicalWellBeing SocialSupport        0.995  94.165       0 Significant

11.5 H2 R-Square

r2_h2 <- inspect(fit_h2, "r2")

print(round(r2_h2, 4))
##               social_support teacher_student_relationship 
##                        0.549                        0.664 
##                    extra_inv                 bullying_inv 
##                        0.580                        0.662 
##                  self_esteem               depression_inv 
##                        0.683                        0.704 
##                sleep_quality    mental_health_history_inv 
##                        0.677                        0.536 
##       PsychologicalWellBeing 
##                        0.991

11.6 H2 Path Diagram

semPaths(
  object         = fit_h2,
  what           = "std",
  whatLabels     = "std",
  style          = "ram",
  layout         = "tree",
  rotation       = 2,
  sizeLat        = 9,
  sizeMan        = 6,
  edge.label.cex = 1.1,
  label.cex      = 1,
  residuals      = FALSE,
  intercepts     = FALSE,
  mar            = c(4, 4, 4, 4),
  color = list(
    lat = "#F5B7B1",
    man = "#FDEDEC"
  )
)

title(
  main = "H2: Social Support - Psychological Well-Being",
  cex.main = 1.3,
  font.main = 2
)

After a second attempt was made to split the model into H1 and H2, convergence issues persisted, particularly in the H1 model, which still failed to converge. This suggests that the primary issue lies not in the syntax or the program code used, but rather in the characteristics of the dataset itself. All variables in StressLevelDataset.csv were designed to predict stress levels linearly, resulting in very high correlations among the variables. Consequently, latent constructs such as Academic Stress, Social Support, and Psychological Well-Being become very difficult to empirically distinguish. This condition is evident from latent correlations approaching ±1, indicating high multicollinearity and a lack of discriminant validity among constructs. Therefore, the SEM model becomes statistically unstable, and the model parameters cannot be estimated properly.

Multivariate Analysis Last Task, Data Science UNESA 2024