Import Library

library(lavaan)
## Warning: package 'lavaan' was built under R version 4.5.3
## This is lavaan 0.6-21
## lavaan is FREE software! Please report any bugs.
library(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(car)
## Warning: package 'car' was built under R version 4.5.3
## Loading required package: carData
## Warning: package 'carData' was built under R version 4.5.3
## Registered S3 method overwritten by 'car':
##   method           from
##   na.action.merMod lme4
## 
## Attaching package: 'car'
## The following object is masked from 'package:psych':
## 
##     logit
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.5.3
## 
## Attaching package: 'dplyr'
## The following object is masked from 'package:car':
## 
##     recode
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
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

1. Import dan Cek Struktur Data

data <- read.csv("C:/Users/Lenovo/Downloads/WA_Fn-UseC_-HR-Employee-Attrition (1).csv")

dim(data)
## [1] 1470   35
str(data)
## 'data.frame':    1470 obs. of  35 variables:
##  $ Age                     : int  41 49 37 33 27 32 59 30 38 36 ...
##  $ Attrition               : chr  "Yes" "No" "Yes" "No" ...
##  $ BusinessTravel          : chr  "Travel_Rarely" "Travel_Frequently" "Travel_Rarely" "Travel_Frequently" ...
##  $ DailyRate               : int  1102 279 1373 1392 591 1005 1324 1358 216 1299 ...
##  $ Department              : chr  "Sales" "Research & Development" "Research & Development" "Research & Development" ...
##  $ DistanceFromHome        : int  1 8 2 3 2 2 3 24 23 27 ...
##  $ Education               : int  2 1 2 4 1 2 3 1 3 3 ...
##  $ EducationField          : chr  "Life Sciences" "Life Sciences" "Other" "Life Sciences" ...
##  $ EmployeeCount           : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ EmployeeNumber          : int  1 2 4 5 7 8 10 11 12 13 ...
##  $ EnvironmentSatisfaction : int  2 3 4 4 1 4 3 4 4 3 ...
##  $ Gender                  : chr  "Female" "Male" "Male" "Female" ...
##  $ HourlyRate              : int  94 61 92 56 40 79 81 67 44 94 ...
##  $ JobInvolvement          : int  3 2 2 3 3 3 4 3 2 3 ...
##  $ JobLevel                : int  2 2 1 1 1 1 1 1 3 2 ...
##  $ JobRole                 : chr  "Sales Executive" "Research Scientist" "Laboratory Technician" "Research Scientist" ...
##  $ JobSatisfaction         : int  4 2 3 3 2 4 1 3 3 3 ...
##  $ MaritalStatus           : chr  "Single" "Married" "Single" "Married" ...
##  $ MonthlyIncome           : int  5993 5130 2090 2909 3468 3068 2670 2693 9526 5237 ...
##  $ MonthlyRate             : int  19479 24907 2396 23159 16632 11864 9964 13335 8787 16577 ...
##  $ NumCompaniesWorked      : int  8 1 6 1 9 0 4 1 0 6 ...
##  $ Over18                  : chr  "Y" "Y" "Y" "Y" ...
##  $ OverTime                : chr  "Yes" "No" "Yes" "Yes" ...
##  $ PercentSalaryHike       : int  11 23 15 11 12 13 20 22 21 13 ...
##  $ PerformanceRating       : int  3 4 3 3 3 3 4 4 4 3 ...
##  $ RelationshipSatisfaction: int  1 4 2 3 4 3 1 2 2 2 ...
##  $ StandardHours           : int  80 80 80 80 80 80 80 80 80 80 ...
##  $ StockOptionLevel        : int  0 1 0 0 1 0 3 1 0 2 ...
##  $ TotalWorkingYears       : int  8 10 7 8 6 8 12 1 10 17 ...
##  $ TrainingTimesLastYear   : int  0 3 3 3 3 2 3 2 2 3 ...
##  $ WorkLifeBalance         : int  1 3 3 3 3 2 2 3 3 2 ...
##  $ YearsAtCompany          : int  6 10 0 8 2 7 1 1 9 7 ...
##  $ YearsInCurrentRole      : int  4 7 0 7 2 7 0 0 7 7 ...
##  $ YearsSinceLastPromotion : int  0 1 0 3 2 3 0 0 1 7 ...
##  $ YearsWithCurrManager    : int  5 7 0 0 2 6 0 0 8 7 ...
head(data, 5)
##   Age Attrition    BusinessTravel DailyRate             Department
## 1  41       Yes     Travel_Rarely      1102                  Sales
## 2  49        No Travel_Frequently       279 Research & Development
## 3  37       Yes     Travel_Rarely      1373 Research & Development
## 4  33        No Travel_Frequently      1392 Research & Development
## 5  27        No     Travel_Rarely       591 Research & Development
##   DistanceFromHome Education EducationField EmployeeCount EmployeeNumber
## 1                1         2  Life Sciences             1              1
## 2                8         1  Life Sciences             1              2
## 3                2         2          Other             1              4
## 4                3         4  Life Sciences             1              5
## 5                2         1        Medical             1              7
##   EnvironmentSatisfaction Gender HourlyRate JobInvolvement JobLevel
## 1                       2 Female         94              3        2
## 2                       3   Male         61              2        2
## 3                       4   Male         92              2        1
## 4                       4 Female         56              3        1
## 5                       1   Male         40              3        1
##                 JobRole JobSatisfaction MaritalStatus MonthlyIncome MonthlyRate
## 1       Sales Executive               4        Single          5993       19479
## 2    Research Scientist               2       Married          5130       24907
## 3 Laboratory Technician               3        Single          2090        2396
## 4    Research Scientist               3       Married          2909       23159
## 5 Laboratory Technician               2       Married          3468       16632
##   NumCompaniesWorked Over18 OverTime PercentSalaryHike PerformanceRating
## 1                  8      Y      Yes                11                 3
## 2                  1      Y       No                23                 4
## 3                  6      Y      Yes                15                 3
## 4                  1      Y      Yes                11                 3
## 5                  9      Y       No                12                 3
##   RelationshipSatisfaction StandardHours StockOptionLevel TotalWorkingYears
## 1                        1            80                0                 8
## 2                        4            80                1                10
## 3                        2            80                0                 7
## 4                        3            80                0                 8
## 5                        4            80                1                 6
##   TrainingTimesLastYear WorkLifeBalance YearsAtCompany YearsInCurrentRole
## 1                     0               1              6                  4
## 2                     3               3             10                  7
## 3                     3               3              0                  0
## 4                     3               3              8                  7
## 5                     3               3              2                  2
##   YearsSinceLastPromotion YearsWithCurrManager
## 1                       0                    5
## 2                       1                    7
## 3                       0                    0
## 4                       3                    0
## 5                       2                    2
names(data)
##  [1] "Age"                      "Attrition"               
##  [3] "BusinessTravel"           "DailyRate"               
##  [5] "Department"               "DistanceFromHome"        
##  [7] "Education"                "EducationField"          
##  [9] "EmployeeCount"            "EmployeeNumber"          
## [11] "EnvironmentSatisfaction"  "Gender"                  
## [13] "HourlyRate"               "JobInvolvement"          
## [15] "JobLevel"                 "JobRole"                 
## [17] "JobSatisfaction"          "MaritalStatus"           
## [19] "MonthlyIncome"            "MonthlyRate"             
## [21] "NumCompaniesWorked"       "Over18"                  
## [23] "OverTime"                 "PercentSalaryHike"       
## [25] "PerformanceRating"        "RelationshipSatisfaction"
## [27] "StandardHours"            "StockOptionLevel"        
## [29] "TotalWorkingYears"        "TrainingTimesLastYear"   
## [31] "WorkLifeBalance"          "YearsAtCompany"          
## [33] "YearsInCurrentRole"       "YearsSinceLastPromotion" 
## [35] "YearsWithCurrManager"

2. Seleksi Variabel

data_selected <- data %>%
  select(
    MonthlyIncome, JobLevel, TotalWorkingYears,
    YearsAtCompany, YearsInCurrentRole,
    YearsSinceLastPromotion, YearsWithCurrManager
  )

str(data_selected)
## 'data.frame':    1470 obs. of  7 variables:
##  $ MonthlyIncome          : int  5993 5130 2090 2909 3468 3068 2670 2693 9526 5237 ...
##  $ JobLevel               : int  2 2 1 1 1 1 1 1 3 2 ...
##  $ TotalWorkingYears      : int  8 10 7 8 6 8 12 1 10 17 ...
##  $ YearsAtCompany         : int  6 10 0 8 2 7 1 1 9 7 ...
##  $ YearsInCurrentRole     : int  4 7 0 7 2 7 0 0 7 7 ...
##  $ YearsSinceLastPromotion: int  0 1 0 3 2 3 0 0 1 7 ...
##  $ YearsWithCurrManager   : int  5 7 0 0 2 6 0 0 8 7 ...
dim(data_selected)
## [1] 1470    7

3. Pre-Processing

3.1 Cek Missing Value dan Duplikasi

sum(is.na(data_selected))
## [1] 0
colMeans(is.na(data_selected)) * 100
##           MonthlyIncome                JobLevel       TotalWorkingYears 
##                       0                       0                       0 
##          YearsAtCompany      YearsInCurrentRole YearsSinceLastPromotion 
##                       0                       0                       0 
##    YearsWithCurrManager 
##                       0
duplikat <- data_selected[duplicated(data_selected), ]
nrow(duplikat)
## [1] 2

3.2 Konversi ke Numerik

data_numeric <- data_selected
for (col in colnames(data_numeric)) {
  if (!is.numeric(data_numeric[[col]])) {
    data_numeric[[col]] <- as.numeric(as.factor(data_numeric[[col]]))
  }
}

str(data_numeric)
## 'data.frame':    1470 obs. of  7 variables:
##  $ MonthlyIncome          : int  5993 5130 2090 2909 3468 3068 2670 2693 9526 5237 ...
##  $ JobLevel               : int  2 2 1 1 1 1 1 1 3 2 ...
##  $ TotalWorkingYears      : int  8 10 7 8 6 8 12 1 10 17 ...
##  $ YearsAtCompany         : int  6 10 0 8 2 7 1 1 9 7 ...
##  $ YearsInCurrentRole     : int  4 7 0 7 2 7 0 0 7 7 ...
##  $ YearsSinceLastPromotion: int  0 1 0 3 2 3 0 0 1 7 ...
##  $ YearsWithCurrManager   : int  5 7 0 0 2 6 0 0 8 7 ...

4. Statistika Deskriptif

summary(data_numeric)
##  MonthlyIncome      JobLevel     TotalWorkingYears YearsAtCompany  
##  Min.   : 1009   Min.   :1.000   Min.   : 0.00     Min.   : 0.000  
##  1st Qu.: 2911   1st Qu.:1.000   1st Qu.: 6.00     1st Qu.: 3.000  
##  Median : 4919   Median :2.000   Median :10.00     Median : 5.000  
##  Mean   : 6503   Mean   :2.064   Mean   :11.28     Mean   : 7.008  
##  3rd Qu.: 8379   3rd Qu.:3.000   3rd Qu.:15.00     3rd Qu.: 9.000  
##  Max.   :19999   Max.   :5.000   Max.   :40.00     Max.   :40.000  
##  YearsInCurrentRole YearsSinceLastPromotion YearsWithCurrManager
##  Min.   : 0.000     Min.   : 0.000          Min.   : 0.000      
##  1st Qu.: 2.000     1st Qu.: 0.000          1st Qu.: 2.000      
##  Median : 3.000     Median : 1.000          Median : 3.000      
##  Mean   : 4.229     Mean   : 2.188          Mean   : 4.123      
##  3rd Qu.: 7.000     3rd Qu.: 3.000          3rd Qu.: 7.000      
##  Max.   :18.000     Max.   :15.000          Max.   :17.000
describe(data_numeric)
##                         vars    n    mean      sd median trimmed     mad  min
## MonthlyIncome              1 1470 6502.93 4707.96   4919 5667.24 3260.24 1009
## JobLevel                   2 1470    2.06    1.11      2    1.90    1.48    1
## TotalWorkingYears          3 1470   11.28    7.78     10   10.37    5.93    0
## YearsAtCompany             4 1470    7.01    6.13      5    5.99    4.45    0
## YearsInCurrentRole         5 1470    4.23    3.62      3    3.85    4.45    0
## YearsSinceLastPromotion    6 1470    2.19    3.22      1    1.48    1.48    0
## YearsWithCurrManager       7 1470    4.12    3.57      3    3.77    4.45    0
##                           max range skew kurtosis     se
## MonthlyIncome           19999 18990 1.37     0.99 122.79
## JobLevel                    5     4 1.02     0.39   0.03
## TotalWorkingYears          40    40 1.11     0.91   0.20
## YearsAtCompany             40    40 1.76     3.91   0.16
## YearsInCurrentRole         18    18 0.92     0.47   0.09
## YearsSinceLastPromotion    15    15 1.98     3.59   0.08
## YearsWithCurrManager       17    17 0.83     0.16   0.09

Hasil statistik deskriptif menunjukkan bahwa variabel MonthlyIncome memiliki rata-rata sebesar 6502.93 dengan standar deviasi sebesar 4707.96, yang menunjukkan adanya variasi pendapatan yang cukup besar antar karyawan. Variabel TotalWorkingYears memiliki rata-rata pengalaman kerja sebesar 11.28 tahun, sedangkan YearsAtCompany memiliki rata-rata masa kerja sebesar 7.01 tahun. Variabel YearsSinceLastPromotion memiliki rata-rata sebesar 2.19 tahun, yang menunjukkan sebagian besar karyawan belum lama memperoleh promosi jabatan.

5. Normalisasi Z-Score

data_z <- as.data.frame(lapply(data_numeric, function(x) {
  if (is.numeric(x)) (x - mean(x, na.rm = TRUE)) / sd(x, na.rm = TRUE)
  else x
}))

head(data_z)
##   MonthlyIncome    JobLevel TotalWorkingYears YearsAtCompany YearsInCurrentRole
## 1    -0.1083127 -0.05776789        -0.4214990   -0.164557109        -0.06327437
## 2    -0.2916193 -0.05776789        -0.1644554    0.488341541         0.76473737
## 3    -0.9373347 -0.96115930        -0.5500208   -1.143905083        -1.16729002
## 4    -0.7633739 -0.96115930        -0.4214990    0.161892216         0.76473737
## 5    -0.6446387 -0.96115930        -0.6785426   -0.817455758        -0.61528219
## 6    -0.7296013 -0.96115930        -0.4214990   -0.001332446         0.76473737
##   YearsSinceLastPromotion YearsWithCurrManager
## 1             -0.67891464            0.2457504
## 2             -0.36858985            0.8062671
## 3             -0.67891464           -1.1555415
## 4              0.25205973           -1.1555415
## 5             -0.05826506           -0.5950247
## 6              0.25205973            0.5260087
round(colMeans(data_z), 4)
##           MonthlyIncome                JobLevel       TotalWorkingYears 
##                       0                       0                       0 
##          YearsAtCompany      YearsInCurrentRole YearsSinceLastPromotion 
##                       0                       0                       0 
##    YearsWithCurrManager 
##                       0

6. Visualisasi Distribusi Data

par(mfrow = c(2, 4), mar = c(4, 4, 2, 1))
for (col in colnames(data_z)) {
  hist(data_z[[col]], main = col, xlab = col,
       col = "darkblue", border = "white")
}
par(mfrow = c(1, 1))

Berdasarkan histogram distribusi data, sebagian besar variabel memiliki pola distribusi yang cukup baik. Namun, beberapa variabel seperti MonthlyIncome, YearsAtCompany, dan YearsSinceLastPromotion terlihat cenderung skewed ke kanan, yang menunjukkan adanya beberapa karyawan dengan nilai jauh lebih tinggi dibandingkan mayoritas responden.

7. Uji Asumsi

7.1 Uji Normalitas Multivariat

mardia(data_z)

## Call: mardia(x = data_z)
## 
## Mardia tests of multivariate skew and kurtosis
## Use describe(x) the to get univariate tests
## n.obs = 1470   num.vars =  7 
## b1p =  28.83   skew =  7062.76  with probability  <=  0
##  small sample skew =  7080.78  with probability <=  0
## b2p =  110.28   kurtosis =  80.74  with probability <=  0

Hasil uji normalitas multivariat menggunakan Mardia menunjukkan nilai skew sebesar 7062.76 dan kurtosis sebesar 80.74 dengan probabilitas ≤ 0.05. Hal ini menunjukkan bahwa data belum memenuhi asumsi normalitas multivariat secara sempurna. Namun, karena jumlah sampel penelitian cukup besar yaitu 1470 observasi, analisis SEM masih dapat dilakukan.

7.2 KMO

r <- cor(data_z)
KMO(r)
## Kaiser-Meyer-Olkin factor adequacy
## Call: KMO(r = r)
## Overall MSA =  0.83
## MSA for each item = 
##           MonthlyIncome                JobLevel       TotalWorkingYears 
##                    0.73                    0.73                    0.95 
##          YearsAtCompany      YearsInCurrentRole YearsSinceLastPromotion 
##                    0.84                    0.88                    0.93 
##    YearsWithCurrManager 
##                    0.86

Hasil uji KMO memperoleh nilai Overall MSA sebesar 0.83. Karena nilai KMO lebih besar dari 0.50, maka data dinyatakan layak dan memadai untuk dilakukan analisis faktor. Nilai MSA masing-masing variabel juga berada di atas 0.50, sehingga seluruh indikator dapat digunakan dalam analisis lanjutan.

7.3 Uji Multikolinearitas (VIF)

data_vif <- na.omit(data_z)

model_vif <- lm(YearsAtCompany ~ MonthlyIncome + JobLevel +
                  TotalWorkingYears + YearsInCurrentRole +
                  YearsSinceLastPromotion + YearsWithCurrManager,
                data = data_vif)

vif(model_vif)
##           MonthlyIncome                JobLevel       TotalWorkingYears 
##               10.670736               11.067071                2.946665 
##      YearsInCurrentRole YearsSinceLastPromotion    YearsWithCurrManager 
##                2.310836                1.541154                2.208788

Hasil uji multikolinearitas menunjukkan bahwa sebagian besar variabel memiliki nilai VIF di bawah 10, sehingga tidak terjadi multikolinearitas yang serius. Namun, variabel MonthlyIncome memiliki nilai VIF sebesar 10.67 dan JobLevel sebesar 11.07, yang menunjukkan adanya hubungan yang cukup kuat antara kedua variabel tersebut.

8. Confirmatory Factor Analysis (CFA) per Konstruk

8.1 CFA X Faktor Sosial Ekonomi Karyawan

model_cfa_x <- '
  SosialEkonomi =~ MonthlyIncome + JobLevel + TotalWorkingYears
'

fit_x <- cfa(model_cfa_x, data = data_z, std.lv = TRUE)
summary(fit_x, fit.measures = TRUE, standardized = TRUE)
## lavaan 0.6-21 ended normally after 30 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                         6
## 
##   Number of observations                          1470
## 
## Model Test User Model:
##                                                       
##   Test statistic                                 0.000
##   Degrees of freedom                                 0
## 
## Model Test Baseline Model:
## 
##   Test statistic                              4856.332
##   Degrees of freedom                                 3
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    1.000
##   Tucker-Lewis Index (TLI)                       1.000
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -3827.853
##   Loglikelihood unrestricted model (H1)      -3827.853
##                                                       
##   Akaike (AIC)                                7667.705
##   Bayesian (BIC)                              7699.463
##   Sample-size adjusted Bayesian (SABIC)       7680.403
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.000
##   90 Percent confidence interval - lower         0.000
##   90 Percent confidence interval - upper         0.000
##   P-value H_0: RMSEA <= 0.050                       NA
##   P-value H_0: RMSEA >= 0.080                       NA
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.000
## 
## 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
##   SosialEkonomi =~                                                      
##     MonthlyIncome     0.969    0.019   50.317    0.000    0.969    0.969
##     JobLevel          0.980    0.019   51.447    0.000    0.980    0.981
##     TotalWorkngYrs    0.797    0.022   36.766    0.000    0.797    0.798
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .MonthlyIncome     0.061    0.007    9.355    0.000    0.061    0.061
##    .JobLevel          0.038    0.006    5.951    0.000    0.038    0.038
##    .TotalWorkngYrs    0.364    0.014   25.902    0.000    0.364    0.364
##     SosialEkonomi     1.000                               1.000    1.000

Hasil CFA pada konstruk SosialEkonomi menunjukkan bahwa seluruh indikator memiliki loading factor yang tinggi, yaitu MonthlyIncome sebesar 0.969, JobLevel sebesar 0.981, dan TotalWorkingYears sebesar 0.798. Seluruh nilai loading factor berada di atas 0.50 sehingga seluruh indikator dinyatakan valid dalam merepresentasikan konstruk SosialEkonomi.

8.2 CFA Y Stabilitas Karir Karyawan

model_cfa_y <- '
  StabilitasKarir =~ YearsAtCompany + YearsInCurrentRole +
                     YearsSinceLastPromotion + YearsWithCurrManager
'

fit_y <- cfa(model_cfa_y, data = data_z, std.lv = TRUE)
summary(fit_y, fit.measures = TRUE, standardized = TRUE)
## lavaan 0.6-21 ended normally after 20 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                         8
## 
##   Number of observations                          1470
## 
## Model Test User Model:
##                                                       
##   Test statistic                                23.305
##   Degrees of freedom                                 2
##   P-value (Chi-square)                           0.000
## 
## Model Test Baseline Model:
## 
##   Test statistic                              3474.113
##   Degrees of freedom                                 6
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    0.994
##   Tucker-Lewis Index (TLI)                       0.982
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -6615.954
##   Loglikelihood unrestricted model (H1)      -6604.301
##                                                       
##   Akaike (AIC)                               13247.908
##   Bayesian (BIC)                             13290.252
##   Sample-size adjusted Bayesian (SABIC)      13264.838
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.085
##   90 Percent confidence interval - lower         0.056
##   90 Percent confidence interval - upper         0.118
##   P-value H_0: RMSEA <= 0.050                    0.024
##   P-value H_0: RMSEA >= 0.080                    0.648
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.014
## 
## 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
##   StabilitasKarir =~                                                      
##     YearsAtCompany      0.918    0.021   44.275    0.000    0.918    0.918
##     YearsInCrrntRl      0.835    0.022   38.239    0.000    0.835    0.835
##     YrsSncLstPrmtn      0.654    0.024   27.262    0.000    0.654    0.655
##     YersWthCrrMngr      0.837    0.022   38.428    0.000    0.837    0.838
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .YearsAtCompany    0.157    0.012   12.595    0.000    0.157    0.157
##    .YearsInCrrntRl    0.303    0.015   20.526    0.000    0.303    0.303
##    .YrsSncLstPrmtn    0.571    0.023   25.152    0.000    0.571    0.572
##    .YersWthCrrMngr    0.298    0.015   20.356    0.000    0.298    0.298
##     StabilitasKarr    1.000                               1.000    1.000

Hasil CFA pada konstruk StabilitasKarir menunjukkan bahwa indikator YearsAtCompany memiliki loading factor sebesar 0.918, YearsInCurrentRole sebesar 0.835, YearsSinceLastPromotion sebesar 0.655, dan YearsWithCurrManager sebesar 0.838. Seluruh indikator memiliki nilai loading factor di atas 0.50 sehingga dinyatakan valid dalam membentuk konstruk StabilitasKarir.

9. Visualisasi CFA

9.1 Visualisasi CFA X

semPaths(fit_x,
         what = "path", whatLabels = "std",
         style = "ram", layout = "tree", rotation = 2,
         sizeMan = 7, sizeLat = 9,
         edge.label.cex = 1.2, label.cex = 1.1,
         color = list(lat = "darkblue", man = "lightyellow"))

Visualisasi CFA pada konstruk SosialEkonomi menunjukkan bahwa seluruh indikator memiliki hubungan yang kuat dengan konstruk laten. Indikator JobLevel memiliki kontribusi terbesar terhadap konstruk SosialEkonomi karena memiliki loading factor tertinggi yaitu sebesar 0.981.

9.2 Visualisasi CFA Y

semPaths(fit_y,
         what = "path", whatLabels = "std",
         style = "ram", layout = "tree", rotation = 2,
         sizeMan = 7, sizeLat = 9,
         edge.label.cex = 1.2, label.cex = 1.1,
         color = list(lat = "darkgreen", man = "lightyellow"))

Visualisasi CFA pada konstruk StabilitasKarir menunjukkan bahwa indikator YearsAtCompany memiliki kontribusi paling besar terhadap konstruk laten dengan loading factor sebesar 0.918. Hal ini menunjukkan bahwa lama bekerja di perusahaan menjadi indikator utama dalam membentuk stabilitas karir karyawan.

10. Fit Indeks CFA

cfa_fits <- data.frame(
  Konstruk  = c("SosialEkonomi (x)", "StabilitasKarir (Y)"),
  CFI       = c(fitMeasures(fit_x, "cfi"),
                fitMeasures(fit_y,  "cfi")),
  TLI       = c(fitMeasures(fit_x, "tli"),
                fitMeasures(fit_y,  "tli")),
  RMSEA     = c(fitMeasures(fit_x, "rmsea"),
                fitMeasures(fit_y,  "rmsea")),
  SRMR      = c(fitMeasures(fit_x, "srmr"),
                fitMeasures(fit_y,  "srmr")),
  ChiSquare = c(fitMeasures(fit_x, "chisq"),
                fitMeasures(fit_y,  "chisq")),
  p_value   = c(fitMeasures(fit_x, "pvalue"),
                fitMeasures(fit_y,  "pvalue"))
)

cfa_fits[, -1] <- round(cfa_fits[, -1], 4)
print(cfa_fits)
##              Konstruk    CFI    TLI  RMSEA   SRMR ChiSquare p_value
## 1   SosialEkonomi (x) 1.0000 1.0000 0.0000 0.0000    0.0000      NA
## 2 StabilitasKarir (Y) 0.9939 0.9816 0.0851 0.0143   23.3048       0

Hasil evaluasi fit indeks menunjukkan bahwa konstruk SosialEkonomi memiliki nilai CFI dan TLI sebesar 1.000 serta RMSEA dan SRMR sebesar 0.000, yang menunjukkan model memiliki kecocokan yang sangat baik. Sementara itu, konstruk StabilitasKarir memiliki nilai CFI sebesar 0.994 dan TLI sebesar 0.982 yang menunjukkan model sudah baik, meskipun nilai RMSEA sebesar 0.085 sedikit berada di atas batas ideal 0.08.

11. Evaluasi Outer Model

11.1 AVE dan CR

hitung_AVE <- function(fit) {
  std    <- standardizedSolution(fit)
  lambda <- std$est[std$op == "=~"]
  AVE    <- sum(lambda^2) / length(lambda)
  return(round(AVE, 4))
}

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

Hasil evaluasi outer model menunjukkan bahwa konstruk SosialEkonomi memiliki nilai AVE sebesar 0.8456 dan CR sebesar 0.9422, sedangkan konstruk StabilitasKarir memiliki nilai AVE sebesar 0.6674 dan CR sebesar 0.8878. Karena seluruh nilai AVE > 0.50 dan CR > 0.70, maka kedua konstruk dinyatakan valid dan reliabel.

11.2 Tabel AVE dan CR

hasil_validitas <- data.frame(
  Konstruk = c("SosialEkonomi (X)", "StabilitasKarir (Y)"),
  AVE      = c(hitung_AVE(fit_x), hitung_AVE(fit_y)),
  CR       = c(hitung_CR(fit_x),  hitung_CR(fit_y))
)

print(hasil_validitas)
##              Konstruk    AVE     CR
## 1   SosialEkonomi (X) 0.8456 0.9422
## 2 StabilitasKarir (Y) 0.6674 0.8878

Hasil uji reliabilitas menunjukkan bahwa konstruk SosialEkonomi memiliki nilai Cronbach Alpha sebesar 0.938 dan StabilitasKarir sebesar 0.883. Nilai tersebut berada di atas 0.70 sehingga kedua konstruk memiliki tingkat reliabilitas yang sangat baik.

11.3 Cronbach Alpha

reliability(fit_x)
## Warning in reliability(fit_x): 
## 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.
##        SosialEkonomi
## alpha      0.9382585
## omega      0.9421928
## omega2     0.9421928
## omega3     0.9421928
## avevar     0.8456392
reliability(fit_y)
## Warning in reliability(fit_y): 
## 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.
##        StabilitasKarir
## alpha        0.8828083
## omega        0.8878276
## omega2       0.8878276
## omega3       0.8894817
## avevar       0.6674061

Hasil validitas diskriminan menggunakan HTMT menunjukkan nilai sebesar 0.578. Karena nilai HTMT berada di bawah 0.90, maka kedua konstruk dapat dibedakan dengan baik dan memenuhi validitas diskriminan.

11.4 Validitas Diskriminan

model_cfa_gabungan <- '
  SosialEkonomi   =~ MonthlyIncome + JobLevel + TotalWorkingYears
  StabilitasKarir =~ YearsAtCompany + YearsInCurrentRole +
                     YearsSinceLastPromotion + YearsWithCurrManager
'

fit_gabungan <- cfa(model_cfa_gabungan, data = data_z, std.lv = TRUE)
summary(fit_gabungan, fit.measures = TRUE, standardized = TRUE)
## lavaan 0.6-21 ended normally after 27 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        15
## 
##   Number of observations                          1470
## 
## Model Test User Model:
##                                                       
##   Test statistic                               346.688
##   Degrees of freedom                                13
##   P-value (Chi-square)                           0.000
## 
## Model Test Baseline Model:
## 
##   Test statistic                              9105.958
##   Degrees of freedom                                21
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    0.963
##   Tucker-Lewis Index (TLI)                       0.941
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)             -10217.741
##   Loglikelihood unrestricted model (H1)     -10044.398
##                                                       
##   Akaike (AIC)                               20465.483
##   Bayesian (BIC)                             20544.878
##   Sample-size adjusted Bayesian (SABIC)      20497.228
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.132
##   90 Percent confidence interval - lower         0.120
##   90 Percent confidence interval - upper         0.144
##   P-value H_0: RMSEA <= 0.050                    0.000
##   P-value H_0: RMSEA >= 0.080                    1.000
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.061
## 
## 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
##   SosialEkonomi =~                                                        
##     MonthlyIncome       0.967    0.019   50.295    0.000    0.967    0.968
##     JobLevel            0.981    0.019   51.648    0.000    0.981    0.981
##     TotalWorkngYrs      0.801    0.022   36.997    0.000    0.801    0.801
##   StabilitasKarir =~                                                      
##     YearsAtCompany      0.939    0.020   46.296    0.000    0.939    0.939
##     YearsInCrrntRl      0.818    0.022   37.307    0.000    0.818    0.819
##     YrsSncLstPrmtn      0.654    0.024   27.383    0.000    0.654    0.654
##     YersWthCrrMngr      0.821    0.022   37.512    0.000    0.821    0.822
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   SosialEkonomi ~~                                                      
##     StabilitasKarr    0.547    0.020   27.799    0.000    0.547    0.547
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .MonthlyIncome     0.064    0.006   10.607    0.000    0.064    0.064
##    .JobLevel          0.037    0.006    6.285    0.000    0.037    0.037
##    .TotalWorkngYrs    0.358    0.014   25.886    0.000    0.358    0.358
##    .YearsAtCompany    0.117    0.011   10.294    0.000    0.117    0.118
##    .YearsInCrrntRl    0.330    0.015   21.938    0.000    0.330    0.330
##    .YrsSncLstPrmtn    0.572    0.022   25.420    0.000    0.572    0.572
##    .YersWthCrrMngr    0.325    0.015   21.796    0.000    0.325    0.325
##     SosialEkonomi     1.000                               1.000    1.000
##     StabilitasKarr    1.000                               1.000    1.000
inspect(fit_gabungan, "cor.lv")
##                 SslEkn StbltK
## SosialEkonomi    1.000       
## StabilitasKarir  0.547  1.000
htmt(model_cfa_gabungan, data = data_z)
##                 SslEkn StbltK
## SosialEkonomi    1.000       
## StabilitasKarir  0.578  1.000

12. Structural Equation Modeling (SEM)

model_sem <- '
  SosialEkonomi =~ MonthlyIncome + JobLevel + TotalWorkingYears

  StabilitasKarir =~ YearsAtCompany + YearsInCurrentRole +
                     YearsSinceLastPromotion + YearsWithCurrManager

  StabilitasKarir ~ SosialEkonomi
'

fit_sem <- sem(model_sem, data = data_z, std.lv = TRUE)
summary(fit_sem, fit.measures = TRUE, standardized = TRUE)
## lavaan 0.6-21 ended normally after 28 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        15
## 
##   Number of observations                          1470
## 
## Model Test User Model:
##                                                       
##   Test statistic                               346.688
##   Degrees of freedom                                13
##   P-value (Chi-square)                           0.000
## 
## Model Test Baseline Model:
## 
##   Test statistic                              9105.958
##   Degrees of freedom                                21
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    0.963
##   Tucker-Lewis Index (TLI)                       0.941
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)             -10217.741
##   Loglikelihood unrestricted model (H1)     -10044.398
##                                                       
##   Akaike (AIC)                               20465.483
##   Bayesian (BIC)                             20544.878
##   Sample-size adjusted Bayesian (SABIC)      20497.228
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.132
##   90 Percent confidence interval - lower         0.120
##   90 Percent confidence interval - upper         0.144
##   P-value H_0: RMSEA <= 0.050                    0.000
##   P-value H_0: RMSEA >= 0.080                    1.000
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.061
## 
## 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
##   SosialEkonomi =~                                                        
##     MonthlyIncome       0.967    0.019   50.295    0.000    0.967    0.968
##     JobLevel            0.981    0.019   51.648    0.000    0.981    0.981
##     TotalWorkngYrs      0.801    0.022   36.998    0.000    0.801    0.801
##   StabilitasKarir =~                                                      
##     YearsAtCompany      0.786    0.018   44.220    0.000    0.939    0.939
##     YearsInCrrntRl      0.685    0.019   36.564    0.000    0.818    0.819
##     YrsSncLstPrmtn      0.547    0.020   27.078    0.000    0.654    0.654
##     YersWthCrrMngr      0.687    0.019   36.758    0.000    0.821    0.822
## 
## Regressions:
##                     Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   StabilitasKarir ~                                                      
##     SosialEkonomi      0.654    0.034   19.477    0.000    0.547    0.547
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .MonthlyIncome     0.064    0.006   10.607    0.000    0.064    0.064
##    .JobLevel          0.037    0.006    6.285    0.000    0.037    0.037
##    .TotalWorkngYrs    0.358    0.014   25.886    0.000    0.358    0.358
##    .YearsAtCompany    0.117    0.011   10.294    0.000    0.117    0.118
##    .YearsInCrrntRl    0.330    0.015   21.938    0.000    0.330    0.330
##    .YrsSncLstPrmtn    0.572    0.022   25.420    0.000    0.572    0.572
##    .YersWthCrrMngr    0.325    0.015   21.796    0.000    0.325    0.325
##     SosialEkonomi     1.000                               1.000    1.000
##    .StabilitasKarr    1.000                               0.701    0.701

Hasil SEM menunjukkan bahwa seluruh indikator tetap memiliki loading factor yang baik terhadap konstruk laten masing-masing. Konstruk SosialEkonomi memiliki hubungan positif terhadap StabilitasKarir dengan standardized coefficient sebesar 0.547, yang menunjukkan bahwa peningkatan kondisi sosial ekonomi akan meningkatkan stabilitas karir karyawan.

13. Evaluasi Inner Model SEM

fit_indices <- data.frame(
  Indeks    = c("Chi-Square", "df", "p-value", "CFI",
                "TLI", "RMSEA", "SRMR", "GFI"),
  Nilai     = round(c(
    fitMeasures(fit_sem, "chisq"),
    fitMeasures(fit_sem, "df"),
    fitMeasures(fit_sem, "pvalue"),
    fitMeasures(fit_sem, "cfi"),
    fitMeasures(fit_sem, "tli"),
    fitMeasures(fit_sem, "rmsea"),
    fitMeasures(fit_sem, "srmr"),
    fitMeasures(fit_sem, "gfi")
  ), 4),
  Threshold = c("> 0.05", "—", "> 0.05", ">= 0.90",
                ">= 0.90", "< 0.08", "< 0.05", ">= 0.90")
)

print(fit_indices)
##            Indeks    Nilai Threshold
## chisq  Chi-Square 346.6877    > 0.05
## df             df  13.0000         —
## pvalue    p-value   0.0000    > 0.05
## cfi           CFI   0.9633   >= 0.90
## tli           TLI   0.9407   >= 0.90
## rmsea       RMSEA   0.1321    < 0.08
## srmr         SRMR   0.0612    < 0.05
## gfi           GFI   0.9398   >= 0.90

Hasil evaluasi model SEM menunjukkan nilai CFI sebesar 0.963, TLI sebesar 0.941, dan GFI sebesar 0.940 yang menunjukkan model memiliki goodness of fit yang baik. Nilai SRMR sebesar 0.061 masih berada dalam kategori acceptable fit, meskipun nilai RMSEA sebesar 0.132 menunjukkan model belum sepenuhnya optimal.

14. Uji Hipotesis dan Koefisien Jalur

hasil_sem <- parameterEstimates(fit_sem, standardized = TRUE)

path_coef <- hasil_sem[hasil_sem$op == "~",
                       c("lhs", "rhs", "est", "se", "z", "pvalue", "std.all")]

colnames(path_coef) <- c("Endogen", "Eksogen", "Estimasi",
                         "Std.Error", "z-value", "p-value", "Std.Koef")

path_coef[, 3:7] <- round(path_coef[, 3:7], 4)
print(path_coef)
##           Endogen       Eksogen Estimasi Std.Error z.value p.value Std.Koef
## 8 StabilitasKarir SosialEkonomi    0.654     0.034  19.477       0    0.547
for (i in 1:nrow(path_coef)) {
  status <- ifelse(path_coef$`p-value`[i] < 0.05, "SIGNIFIKAN", "TIDAK SIGNIFIKAN")
  arah   <- ifelse(path_coef$Estimasi[i] > 0, "POSITIF (+)", "NEGATIF (-)")
  cat(sprintf("H%d: %s -> %s | p = %.4f | Arah: %s | %s\n",
              i,
              path_coef$Eksogen[i],
              path_coef$Endogen[i],
              path_coef$`p-value`[i],
              arah,
              status))
}
## H1: SosialEkonomi -> StabilitasKarir | p = 0.0000 | Arah: POSITIF (+) | SIGNIFIKAN

Hasil pengujian hipotesis menunjukkan bahwa hubungan SosialEkonomi terhadap StabilitasKarir memiliki nilai estimasi sebesar 0.654 dengan z-value sebesar 19.477 dan p-value sebesar 0.000. Nilai tersebut menunjukkan bahwa SosialEkonomi berpengaruh positif dan signifikan terhadap StabilitasKarir, sehingga hipotesis penelitian diterima.

15. Visualisasi SEM

semPaths(fit_sem,
         what           = "path",
         whatLabels     = "std",
         style          = "ram",
         layout         = "tree2",
         rotation       = 2,
         sizeMan        = 5,
         sizeLat        = 8,
         edge.label.cex = 0.9,
         label.cex      = 0.9,
         color          = list(lat = "darkblue", man = "lightyellow"),
         edge.color     = "gray40")

Visualisasi SEM menunjukkan adanya hubungan positif antara konstruk SosialEkonomi dan StabilitasKarir. Jalur hubungan antar konstruk memiliki koefisien standar sebesar 0.547 yang menunjukkan pengaruh dalam kategori sedang hingga kuat. Seluruh indikator juga terlihat memiliki hubungan yang kuat terhadap konstruk laten masing-masing.