Tahap 1: Setup dan Inisialisasi Lingkungan Kerja

Pada tahap awal ini, kita akan mempersiapkan lingkungan kerja R dengan memuat pustaka (libraries) yang esensial untuk analisis Structural Equation Modeling (SEM). Pustaka utama yang digunakan adalah lavaan untuk komputasi model, semPlot untuk visualisasi diagram jalur (path diagram), psych untuk uji asumsi statistik, dan dplyr untuk manipulasi data.

Selanjutnya, kita akan memuat dataset retail_wlb_dataset.csv ke dalam memori (disimpan dalam variabel df) dan menampilkan dimensi data untuk memastikan proses import berjalan dengan benar. Ekspektasi dari dataset ini adalah 150 baris observasi dan 20 kolom.

# Mengaktifkan pustaka yang dibutuhkan
# Hapus tanda pagar pada baris install.packages jika pustaka belum terinstal di environment Anda
# install.packages(c("lavaan", "semPlot", "psych", "dplyr"))

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(semPlot)
## Warning: package 'semPlot' was built under R version 4.5.3
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(dplyr)
## 
## 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
# Memuat dataset
df <- read.csv("retail_wlb_dataset.csv")

# Memeriksa dimensi dataset (baris, kolom) dan struktur awal
dim(df)
## [1] 150  20
glimpse(df) # Fungsi dari dplyr untuk melihat ringkasan tipe data per kolom
## Rows: 150
## Columns: 20
## $ Age                    <int> 56, 46, 32, 25, 38, 56, 36, 40, 28, 28, 41, 53,…
## $ Gender                 <chr> "Female", "Female", "Female", "Female", "Female…
## $ Experience_Years       <dbl> 18.0, 18.1, 12.8, 7.1, 7.3, 14.7, 18.0, 17.8, 1…
## $ Job_Role               <chr> "Supervisor", "Customer Service", "Cashier", "S…
## $ Working_Hours_Per_Week <int> 32, 41, 54, 49, 50, 33, 50, 52, 45, 54, 36, 42,…
## $ WLB1                   <dbl> 4, 3, 2, 5, 3, 4, 2, 3, 3, 4, 3, 3, 2, 3, 3, 4,…
## $ WLB2                   <dbl> 4, 3, 3, 4, 3, 4, 3, 3, 3, 3, 3, 4, 3, 3, 4, 3,…
## $ WLB3                   <dbl> 4, 3, 2, 4, 4, 4, 2, 2, 3, 3, 3, 4, 2, 4, 4, 3,…
## $ WLB4                   <dbl> 4, 3, 2, 4, 3, 4, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4,…
## $ WLB5                   <dbl> 4, 3, 2, 4, 4, 4, 2, 3, 3, 4, 3, 3, 3, 3, 4, 4,…
## $ JS1                    <dbl> 1, 1, 2, 3, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2,…
## $ JS2                    <dbl> 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 3, 2,…
## $ JS3                    <dbl> 1, 1, 2, 3, 2, 2, 2, 2, 3, 2, 2, 2, 1, 1, 2, 2,…
## $ JS4                    <dbl> 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2,…
## $ JS5                    <dbl> 1, 1, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2,…
## $ EP1                    <dbl> 2, 2, 2, 2, 3, 2, 2, 3, 2, 1, 2, 3, 1, 3, 1, 3,…
## $ EP2                    <dbl> 2, 2, 2, 2, 3, 3, 2, 3, 2, 2, 1, 2, 2, 3, 1, 3,…
## $ EP3                    <dbl> 2, 1, 2, 2, 3, 3, 1, 3, 2, 2, 1, 3, 1, 3, 2, 3,…
## $ EP4                    <dbl> 2, 1, 2, 2, 3, 3, 1, 3, 2, 1, 1, 2, 1, 3, 2, 3,…
## $ EP5                    <dbl> 2, 1, 2, 1, 3, 2, 2, 3, 2, 2, 1, 3, 1, 3, 2, 3,…

Tahap 2: Pra-pemrosesan Data (Data Preprocessing)

Analisis SEM menggunakan metode estimasi yang berfokus pada matriks kovarians antar indikator. Oleh karena itu, kita perlu memisahkan data metrik/indikator dari data demografi. Dataset asli memiliki kolom demografi seperti Age, Gender, Experience_Years, Job_Role, dan Working_Hours_Per_Week yang tidak termasuk dalam persamaan struktural kita.

Pada sel ini, kita akan: 1. Melakukan subsetting untuk hanya mengambil 15 kolom indikator skala Likert (WLB1-WLB5, JS1-JS5, dan EP1-EP5). 2. Memeriksa keberadaan nilai kosong (missing values). Jika terdapat missing values, kita akan menghapusnya (listwise deletion) agar tidak menyebabkan kegagalan iterasi pada algoritma estimasi lavaan. 3. Menampilkan sampel baris data bersih yang siap untuk dianalisis.

# 1. Subsetting data indikator
# Mengambil kolom berawalan WLB, JS, dan EP menggunakan fungsi select dari dplyr
df_sem <- df %>%
  select(WLB1:WLB5, JS1:JS5, EP1:EP5)

# 2. Pemeriksaan missing values
cat("Jumlah missing values pada dataset indikator:", sum(is.na(df_sem)), "\n")
## Jumlah missing values pada dataset indikator: 0
# Menghapus baris yang memiliki missing values (jika ada)
df_clean <- na.omit(df_sem)

# Memastikan kembali dimensi setelah pembersihan
cat("Dimensi data setelah pembersihan:", dim(df_clean)[1], "baris,", dim(df_clean)[2], "kolom\n\n")
## Dimensi data setelah pembersihan: 150 baris, 15 kolom
# 3. Menampilkan 6 baris pertama dari data yang sudah bersih
head(df_clean)

Tahap 3: Uji Asumsi Normalitas Multivariat

Pendekatan Covariance-Based SEM (CB-SEM) yang menggunakan estimator Maximum Likelihood (ML) mensyaratkan agar data berdistribusi normal secara multivariat. Pada sel ini, kita akan melakukan uji asumsi tersebut.

Kita akan menggunakan uji Mardia’s Skewness and Kurtosis dari pustaka psych untuk memeriksa tingkat kemencengan (skewness) dan keruncingan (kurtosis) dari gabungan 15 variabel kita. Jika nilai p-value kurang dari 0.05, ini mengindikasikan pelanggaran asumsi normalitas, yang nantinya harus kita pertimbangkan saat melakukan fitting model.

# Menjalankan uji Mardia untuk mengevaluasi skewness dan kurtosis multivariat
hasil_mardia <- mardia(df_clean, plot = FALSE)

hasil_mardia
## Call: mardia(x = df_clean, plot = FALSE)
## 
## Mardia tests of multivariate skew and kurtosis
## Use describe(x) the to get univariate tests
## n.obs = 150   num.vars =  15 
## b1p =  26.6   skew =  664.91  with probability  <=  0.65
##  small sample skew =  679.9  with probability <=  0.49
## b2p =  252.41   kurtosis =  -0.7  with probability <=  0.48

Artinya, 15 indikator kuesioner kita lolos uji asumsi normalitas multivariat.

Tahap 4: Pendefinisian Model SEM (Syntax Lavaan)

Tahap ini adalah inti dari pemodelan menggunakan pustaka lavaan. Kita akan merakit arsitektur model berdasarkan kerangka konseptual yang telah disepakati. Seluruh struktur ini dituliskan ke dalam satu objek teks (string) yang nantinya akan dibaca oleh algoritma estimasi.

Penting untuk memahami tiga operator utama dalam sintaks lavaan: 1. =~ (Diukur oleh): Digunakan untuk membangun Outer Model. Operator ini mengikat indikator-indikator kuesioner ke dalam satu variabel laten/konstruk. 2. ~ (Diregresi pada / Dipengaruhi oleh): Digunakan untuk membangun Inner Model. Operator ini mendefinisikan jalur kausalitas antar variabel laten. 3. := (Didefinisikan sebagai): Digunakan untuk kalkulasi parameter kustom. Kita menggunakan ini untuk menghitung kekuatan efek mediasi secara matematis.

Untuk mempermudah pelacakan jalur dalam uji mediasi, kita akan memberikan label koefisien: * Label a: Pengaruh Work-Life Balance (WLB) terhadap Job Satisfaction (JS). * Label b: Pengaruh Job Satisfaction (JS) terhadap Employee Performance (EP). * Label c: Pengaruh langsung Work-Life Balance (WLB) terhadap Employee Performance (EP).

# Mendefinisikan blueprint model ke dalam variabel string
model_retail <- '
  # ----------------------------------------------------
  # 1. OUTER MODEL (Measurement Model)
  # ----------------------------------------------------
  WLB =~ WLB1 + WLB2 + WLB3 + WLB4 + WLB5
  JS  =~ JS1 + JS2 + JS3 + JS4 + JS5
  EP  =~ EP1 + EP2 + EP3 + EP4 + EP5

  # ----------------------------------------------------
  # 2. INNER MODEL (Structural Model)
  # ----------------------------------------------------
  # H1: WLB mempengaruhi Job Satisfaction
  JS ~ a * WLB
  
  # H2 & H3: EP dipengaruhi oleh Job Satisfaction dan secara langsung oleh WLB
  EP ~ b * JS + c * WLB

  # ----------------------------------------------------
  # 3. KALKULASI EFEK MEDIASI
  # ----------------------------------------------------
  # Indirect Effect (Efek Mediasi) adalah perkalian jalur a dan b
  indirect_effect := a * b
  
  # Total Effect adalah gabungan pengaruh langsung (c) dan tidak langsung (a*b)
  total_effect := c + (a * b)
'

cat("Arsitektur model 'model_retail' berhasil didefinisikan.\n")
## Arsitektur model 'model_retail' berhasil didefinisikan.

Tahap 5: Eksekusi Estimasi Model

Setelah blueprint model selesai dirancang, kita akan melakukan fitting model menggunakan data riil (df_clean). Berdasarkan hasil uji asumsi di Tahap 3 (uji Mardia) yang menyatakan bahwa data kita berdistribusi normal secara multivariat, kita sangat direkomendasikan untuk menggunakan metode estimasi standar, yaitu Maximum Likelihood (estimator = "ML").

Fungsi summary() akan dipanggil untuk menampilkan ringkasan hasil secara komprehensif, dengan menambahkan argumen: * fit.measures = TRUE: Untuk menampilkan metrik evaluasi kelayakan model (seperti RMSEA, CFI, TLI). * standardized = TRUE: Untuk menampilkan koefisien terstandardisasi agar skala nilainya seragam dan mudah dibandingkan. * rsquare = TRUE: Untuk melihat nilai R-squared (\(R^2\)) dari variabel dependen.

# Mengeksekusi model SEM
fit_retail <- sem(model_retail, data = df_clean, estimator = "ML")

# Menampilkan ringkasan hasil analisis
summary(fit_retail, fit.measures = TRUE, standardized = TRUE, rsquare = TRUE)
## lavaan 0.6-21 ended normally after 50 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        33
## 
##   Number of observations                           150
## 
## Model Test User Model:
##                                                       
##   Test statistic                               100.650
##   Degrees of freedom                                87
##   P-value (Chi-square)                           0.150
## 
## Model Test Baseline Model:
## 
##   Test statistic                              1783.505
##   Degrees of freedom                               105
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    0.992
##   Tucker-Lewis Index (TLI)                       0.990
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -1606.878
##   Loglikelihood unrestricted model (H1)      -1556.553
##                                                       
##   Akaike (AIC)                                3279.756
##   Bayesian (BIC)                              3379.107
##   Sample-size adjusted Bayesian (SABIC)       3274.668
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.032
##   90 Percent confidence interval - lower         0.000
##   90 Percent confidence interval - upper         0.057
##   P-value H_0: RMSEA <= 0.050                    0.864
##   P-value H_0: RMSEA >= 0.080                    0.000
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.036
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   WLB =~                                                                
##     WLB1              1.000                               0.641    0.866
##     WLB2              0.890    0.072   12.431    0.000    0.570    0.812
##     WLB3              0.950    0.078   12.216    0.000    0.609    0.803
##     WLB4              0.907    0.072   12.623    0.000    0.581    0.819
##     WLB5              0.979    0.075   13.101    0.000    0.627    0.838
##   JS =~                                                                 
##     JS1               1.000                               0.570    0.837
##     JS2               1.044    0.080   13.008    0.000    0.595    0.857
##     JS3               1.023    0.082   12.408    0.000    0.583    0.831
##     JS4               0.973    0.077   12.619    0.000    0.555    0.840
##     JS5               0.974    0.076   12.749    0.000    0.555    0.846
##   EP =~                                                                 
##     EP1               1.000                               0.604    0.811
##     EP2               1.051    0.089   11.767    0.000    0.634    0.833
##     EP3               1.076    0.090   11.940    0.000    0.649    0.842
##     EP4               1.025    0.089   11.487    0.000    0.618    0.819
##     EP5               0.968    0.083   11.644    0.000    0.584    0.827
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   JS ~                                                                  
##     WLB        (a)    0.482    0.076    6.362    0.000    0.542    0.542
##   EP ~                                                                  
##     JS         (b)    0.549    0.091    6.032    0.000    0.518    0.518
##     WLB        (c)    0.332    0.076    4.372    0.000    0.353    0.353
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .WLB1              0.136    0.021    6.393    0.000    0.136    0.249
##    .WLB2              0.168    0.023    7.212    0.000    0.168    0.341
##    .WLB3              0.203    0.028    7.299    0.000    0.203    0.355
##    .WLB4              0.165    0.023    7.128    0.000    0.165    0.329
##    .WLB5              0.167    0.024    6.892    0.000    0.167    0.298
##    .JS1               0.139    0.020    7.090    0.000    0.139    0.299
##    .JS2               0.129    0.019    6.810    0.000    0.129    0.266
##    .JS3               0.152    0.021    7.162    0.000    0.152    0.309
##    .JS4               0.128    0.018    7.050    0.000    0.128    0.294
##    .JS5               0.123    0.018    6.975    0.000    0.123    0.285
##    .EP1               0.190    0.026    7.265    0.000    0.190    0.343
##    .EP2               0.177    0.025    7.001    0.000    0.177    0.306
##    .EP3               0.173    0.025    6.880    0.000    0.173    0.291
##    .EP4               0.188    0.026    7.174    0.000    0.188    0.329
##    .EP5               0.157    0.022    7.080    0.000    0.157    0.316
##     WLB               0.410    0.063    6.534    0.000    1.000    1.000
##    .JS                0.230    0.038    5.972    0.000    0.706    0.706
##    .EP                0.149    0.028    5.287    0.000    0.409    0.409
## 
## R-Square:
##                    Estimate
##     WLB1              0.751
##     WLB2              0.659
##     WLB3              0.645
##     WLB4              0.671
##     WLB5              0.702
##     JS1               0.701
##     JS2               0.734
##     JS3               0.691
##     JS4               0.706
##     JS5               0.715
##     EP1               0.657
##     EP2               0.694
##     EP3               0.709
##     EP4               0.671
##     EP5               0.684
##     JS                0.294
##     EP                0.591
## 
## Defined Parameters:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##     indirect_effct    0.265    0.056    4.695    0.000    0.281    0.281
##     total_effect      0.597    0.081    7.379    0.000    0.633    0.633

Tahap 6: Evaluasi Outer Model (Measurement Model)

Meskipun model struktural kita sudah terbukti fit pada tahap sebelumnya, kita wajib mendokumentasikan bukti statistik bahwa alat ukur (kuesioner) yang kita gunakan memang valid dan reliabel. Ini adalah inti dari analisis Outer Model.

Kita akan mengevaluasi tiga aspek utama: 1. Validitas Konvergen (Convergent Validity): Mengukur seberapa baik indikator-indikator berkumpul untuk mewakili satu konsep. Metrik yang digunakan adalah Standardized Factor Loading (target > 0.70) dan Average Variance Extracted / AVE (target > 0.50). 2. Reliabilitas Konstruk (Construct Reliability): Mengukur konsistensi kuesioner. Jika tes diulang, apakah hasilnya akan sama? Metrik yang digunakan adalah Composite Reliability / CR atau Omega (target > 0.70). 3. Validitas Diskriminan (Discriminant Validity): Memastikan bahwa konstruk WLB, JS, dan EP benar-benar konsep yang berbeda dan tidak saling tumpang tindih. Kita akan menggunakan kriteria HTMT (Heterotrait-Monotrait Ratio), di mana nilainya harus < 0.90.

Kita akan menggunakan pustaka semTools untuk mengekstrak metrik-metrik tersebut secara otomatis dari model yang sudah kita eksekusi (fit_retail).

# Hapus tanda pagar di bawah ini jika pustaka semTools belum terinstal
# install.packages("semTools")
library(semTools)
## Warning: package 'semTools' was built under R version 4.5.3
## 
## ###############################################################################
## This is semTools 0.5-8
## All users of R (or SEM) are invited to submit functions or ideas for functions.
## ###############################################################################
## 
## Attaching package: 'semTools'
## The following objects are masked from 'package:psych':
## 
##     reliability, skew
cat("=== 1. VALIDITAS KONVERGEN (Standardized Loadings) ===\n")
## === 1. VALIDITAS KONVERGEN (Standardized Loadings) ===
# Mengekstrak matriks koefisien terstandardisasi khusus untuk indikator (=~)
loadings <- standardizedSolution(fit_retail)
loadings_filtered <- subset(loadings, op == "=~")
print(loadings_filtered[, c("lhs", "op", "rhs", "est.std", "pvalue")])
##    lhs op  rhs est.std pvalue
## 1  WLB =~ WLB1   0.866      0
## 2  WLB =~ WLB2   0.812      0
## 3  WLB =~ WLB3   0.803      0
## 4  WLB =~ WLB4   0.819      0
## 5  WLB =~ WLB5   0.838      0
## 6   JS =~  JS1   0.837      0
## 7   JS =~  JS2   0.857      0
## 8   JS =~  JS3   0.831      0
## 9   JS =~  JS4   0.840      0
## 10  JS =~  JS5   0.846      0
## 11  EP =~  EP1   0.811      0
## 12  EP =~  EP2   0.833      0
## 13  EP =~  EP3   0.842      0
## 14  EP =~  EP4   0.819      0
## 15  EP =~  EP5   0.827      0
cat("\n")
cat("=== 2. RELIABILITAS & AVE (Average Variance Extracted) ===\n")
## === 2. RELIABILITAS & AVE (Average Variance Extracted) ===
# Fungsi reliability() dari semTools akan otomatis menghitung Cronbach Alpha, CR (omega), dan AVE
reliabilitas_metrik <- reliability(fit_retail)
## Warning in reliability(fit_retail): 
## The reliability() function was deprecated in 2022 and will cease to be included in future versions of semTools. See help('semTools-deprecated) for details.
## 
## It is replaced by the compRelSEM() function, which can estimate alpha and model-based reliability in an even wider variety of models and data types, with greater control in specifying the desired type of reliability coefficient (i.e., more explicitly choosing assumptions). 
## 
## The average variance extracted should never have been included because it is not a reliability coefficient. It is now available from the AVE() function.
print(reliabilitas_metrik)
##              WLB        JS        EP
## alpha  0.9154543 0.9239800 0.9149659
## omega  0.9160333 0.9242579 0.9151292
## omega2 0.9160333 0.9242579 0.9151292
## omega3 0.9164129 0.9245412 0.9147246
## avevar 0.6861359 0.7095065 0.6834902
cat("\n")
cat("=== 3. VALIDITAS DISKRIMINAN (Metode HTMT) ===\n")
## === 3. VALIDITAS DISKRIMINAN (Metode HTMT) ===
# Menghitung rasio HTMT untuk memastikan tidak ada tumpang tindih antar konsep
htmt_matrix <- htmt(model_retail, data = df_clean)
print(htmt_matrix)
##       WLB    JS    EP
## WLB 1.000            
## JS  0.543 1.000      
## EP  0.631 0.706 1.000

Tahap 7: Visualisasi Path Diagram

Membaca matriks angka yang panjang bisa sangat melelahkan dan sulit dipahami oleh pemangku kepentingan (stakeholders). Oleh karena itu, kita akan menerjemahkan seluruh model struktural dan pengukuran kita ke dalam bentuk visual.

Kita menggunakan pustaka semPlot untuk menghasilkan grafis Path Diagram. Beberapa parameter visualisasi yang kita atur: * whatLabels = "std": Memastikan angka yang muncul di atas panah adalah koefisien terstandardisasi (agar skalanya seragam). * layout = "tree": Mengatur susunan tata letak diagram agar rapi. * rotation = 2: Memutar diagram agar alurnya bergerak masuk akal dari kiri ke kanan (WLB -> JS -> EP). * style = "lisrel": Menggunakan standar visual akademik klasik untuk SEM (Latent = Lingkaran, Indikator = Kotak).

# Memastikan pustaka semPlot sudah aktif
library(semPlot)

cat("Membangun visualisasi Path Diagram...\n")
## Membangun visualisasi Path Diagram...
# Menggambar grafis SEM
semPaths(fit_retail, 
         whatLabels = "std",       # Menampilkan Standardized Loadings & Path Coefficients
         layout = "tree",          # Layout pohon agar rapi
         rotation = 2,             # Alur model dari kiri ke kanan
         style = "lisrel",         # Gaya klasik SEM
         nCharNodes = 0,           # Menampilkan nama variabel secara utuh (tidak disingkat)
         sizeMan = 7,              # Ukuran kotak indikator
         sizeLat = 10,             # Ukuran lingkaran variabel laten
         edge.label.cex = 0.9,     # Ukuran font angka di atas garis panah
         fade = FALSE,             # Warna garis tetap solid (tidak pudar)
         posCol = "darkgreen",     # Warna untuk korelasi/pengaruh positif
         negCol = "red")           # Warna untuk korelasi/pengaruh negatif

# Catatan: Gambar akan muncul di panel "Plots" pada RStudio Anda.