INSTALL & LOAD LIBRARY

library(seminr)
## Warning: package 'seminr' was built under R version 4.5.3
library(psych)
## Warning: package 'psych' was built under R version 4.5.3
library(corrplot)
## Warning: package 'corrplot' was built under R version 4.5.3
## corrplot 0.95 loaded
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.5.3
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(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
## 
## Attaching package: 'car'
## The following object is masked from 'package:dplyr':
## 
##     recode
## The following object is masked from 'package:psych':
## 
##     logit

Bersihkan environment & plot

rm(list = ls(all = TRUE))
graphics.off()

IMPORT & PRE-PROCESSING DATA

Dataset yang digunakan adalah hasil survei Social Media & Mental Health (smmh.csv) dengan 481 responden dan 21 variabel.

data_raw <- read.csv("smmh.csv", header = TRUE)
colnames(data_raw) <- c(
  "Timestamp", "Usia", "Gender", "Status_Hubungan", "Status_Pekerjaan",
  "Organisasi", "Pakai_Medsos", "Platform", "Waktu_Medsos",
  "X1_1_TanpaTujuan", "X1_2_Distraksi", "X1_3_Gelisah", "X1_4_MudahTeralih",
  "Y1_Kekhawatiran", "Y2_SusahKonsentrasi",
  "X2_1_BandingDiri", "X2_2_PerasaanBanding", "X2_3_CariValidasi",
  "Y3_Depresi", "Y4_FluktuasiMinat", "Y5_MasalahTidur"
)

Pilih kolom manifes (indikator) saja

kolom_manifes <- c(
  "X1_1_TanpaTujuan", "X1_2_Distraksi", "X1_3_Gelisah", "X1_4_MudahTeralih",
  "X2_1_BandingDiri", "X2_2_PerasaanBanding", "X2_3_CariValidasi",
  "Y1_Kekhawatiran", "Y2_SusahKonsentrasi",
  "Y3_Depresi", "Y4_FluktuasiMinat", "Y5_MasalahTidur"
)

data <- data_raw[, kolom_manifes]

Pastikan semua numerik

data[] <- lapply(data, function(x) as.numeric(as.character(x)))

Hapus missing value

cat("Total missing sebelum cleaning:", sum(is.na(data)), "\n")
## Total missing sebelum cleaning: 0
data <- na.omit(data)
cat("Jumlah responden valid        :", nrow(data), "\n\n")
## Jumlah responden valid        : 481

Cek duplikat

cat("Jumlah baris duplikat:", sum(duplicated(data)), "\n\n")
## Jumlah baris duplikat: 8

Hapus baris duplikat

data <- data[!duplicated(data), ]

# Verifikasi
cat("Jumlah data sebelum hapus duplikat:", 480, "\n")
## Jumlah data sebelum hapus duplikat: 480
cat("Jumlah data setelah hapus duplikat:", nrow(data), "\n")
## Jumlah data setelah hapus duplikat: 473
cat("Jumlah duplikat yang dihapus      :", 480 - nrow(data), "\n")
## Jumlah duplikat yang dihapus      : 7

ANALISIS DESKRIPTIF

Analisis deskriptif bertujuan untuk menggambarkan karakteristik data secara umum. Nilai mean menunjukkan rata-rata jawaban responden, standar deviasi (SD) menggambarkan sebaran data, serta skewness dan kurtosis digunakan untuk mengindikasikan bentuk distribusi data.

describe() dari psych: n, mean, sd, min, max, skew, kurtosis

desc_stats <- describe(data)
print(round(desc_stats[, c("n","mean","sd","min","max","skew","kurtosis")], 3))
##                        n mean   sd min max  skew kurtosis
## X1_1_TanpaTujuan     473 3.56 1.08   1   5 -0.40    -0.56
## X1_2_Distraksi       473 3.32 1.31   1   5 -0.27    -1.08
## X1_3_Gelisah         473 2.58 1.24   1   5  0.35    -0.87
## X1_4_MudahTeralih    473 3.35 1.16   1   5 -0.16    -0.76
## X2_1_BandingDiri     473 2.82 1.39   1   5  0.20    -1.22
## X2_2_PerasaanBanding 473 2.76 1.03   1   5  0.08    -0.21
## X2_3_CariValidasi    473 2.44 1.23   1   5  0.30    -1.04
## Y1_Kekhawatiran      473 3.56 1.27   1   5 -0.50    -0.86
## Y2_SusahKonsentrasi  473 3.24 1.33   1   5 -0.23    -1.11
## Y3_Depresi           473 3.25 1.30   1   5 -0.22    -1.04
## Y4_FluktuasiMinat    473 3.16 1.24   1   5 -0.09    -1.03
## Y5_MasalahTidur      473 3.20 1.45   1   5 -0.19    -1.36
cat("\n--- Interpretasi Skewness & Kurtosis ---\n")
## 
## --- Interpretasi Skewness & Kurtosis ---
cat("Skewness  : |nilai| < 2 dianggap masih dapat diterima\n")
## Skewness  : |nilai| < 2 dianggap masih dapat diterima
cat("Kurtosis  : |nilai| < 7 dianggap masih dapat diterima\n")
## Kurtosis  : |nilai| < 7 dianggap masih dapat diterima
cat("(Referensi: Hair et al., 2017)\n\n")
## (Referensi: Hair et al., 2017)

Berdasarkan kriteria Hair et al. (2017), nilai |skewness| < 2 dan |kurtosis| < 7 masih dapat diterima untuk analisis multivariate.

VISUALISASI HISTOGRAM

Histogram ditampilkan untuk melihat distribusi jawaban responden pada setiap indikator. Warna biru menunjukkan indikator konstruk X1 (Adiksi Media Sosial), merah untuk X2 (Perbandingan Sosial), dan hijau untuk Y (Kesehatan Mental).

par(mfrow = c(3, 4), mar = c(4, 3, 3, 1))

warna <- c(rep("steelblue", 4),   # X1 biru
           rep("tomato",    3),   # X2 merah
           rep("mediumseagreen", 5)) # Y hijau

for (i in seq_along(kolom_manifes)) {
  col <- kolom_manifes[i]
  hist(data[[col]],
       main   = col,
       xlab   = "Skor (1-5)",
       col    = warna[i],
       border = "white",
       breaks = 5,
       cex.main = 0.85)
}

par(mfrow = c(1, 1))
cat("  Biru  = X1 (Adiksi Medsos)\n")
##   Biru  = X1 (Adiksi Medsos)
cat("  Merah = X2 (Perbandingan Sosial)\n")
##   Merah = X2 (Perbandingan Sosial)
cat("  Hijau = Y  (Kesehatan Mental)\n\n")
##   Hijau = Y  (Kesehatan Mental)

VISUALISASI KORELASI

Matriks korelasi dan heatmap ditampilkan untuk melihat pola hubungan antar indikator. Nilai korelasi yang tinggi antar indikator dalam satu konstruk (> 0.3) mengindikasikan bahwa indikator-indikator tersebut mengukur hal yang sama, yang merupakan syarat konstruk reflektif.

mat_kor <- cor(data, use = "complete.obs")
print(round(mat_kor, 3))
##                      X1_1_TanpaTujuan X1_2_Distraksi X1_3_Gelisah
## X1_1_TanpaTujuan                1.000          0.444        0.335
## X1_2_Distraksi                  0.444          1.000        0.498
## X1_3_Gelisah                    0.335          0.498        1.000
## X1_4_MudahTeralih               0.338          0.591        0.497
## X2_1_BandingDiri                0.119          0.263        0.296
## X2_2_PerasaanBanding            0.045          0.034        0.090
## X2_3_CariValidasi               0.113          0.241        0.212
## Y1_Kekhawatiran                 0.222          0.318        0.325
## Y2_SusahKonsentrasi             0.263          0.510        0.452
## Y3_Depresi                      0.290          0.356        0.305
## Y4_FluktuasiMinat               0.335          0.365        0.362
## Y5_MasalahTidur                 0.236          0.230        0.139
##                      X1_4_MudahTeralih X2_1_BandingDiri X2_2_PerasaanBanding
## X1_1_TanpaTujuan                 0.338            0.119                0.045
## X1_2_Distraksi                   0.591            0.263                0.034
## X1_3_Gelisah                     0.497            0.296                0.090
## X1_4_MudahTeralih                1.000            0.258               -0.039
## X2_1_BandingDiri                 0.258            1.000               -0.062
## X2_2_PerasaanBanding            -0.039           -0.062                1.000
## X2_3_CariValidasi                0.135            0.392                0.102
## Y1_Kekhawatiran                  0.440            0.395               -0.026
## Y2_SusahKonsentrasi              0.649            0.349                0.015
## Y3_Depresi                       0.383            0.397               -0.012
## Y4_FluktuasiMinat                0.457            0.350               -0.004
## Y5_MasalahTidur                  0.264            0.167                0.027
##                      X2_3_CariValidasi Y1_Kekhawatiran Y2_SusahKonsentrasi
## X1_1_TanpaTujuan                 0.113           0.222               0.263
## X1_2_Distraksi                   0.241           0.318               0.510
## X1_3_Gelisah                     0.212           0.325               0.452
## X1_4_MudahTeralih                0.135           0.440               0.649
## X2_1_BandingDiri                 0.392           0.395               0.349
## X2_2_PerasaanBanding             0.102          -0.026               0.015
## X2_3_CariValidasi                1.000           0.179               0.211
## Y1_Kekhawatiran                  0.179           1.000               0.529
## Y2_SusahKonsentrasi              0.211           0.529               1.000
## Y3_Depresi                       0.242           0.573               0.492
## Y4_FluktuasiMinat                0.246           0.408               0.484
## Y5_MasalahTidur                  0.096           0.305               0.333
##                      Y3_Depresi Y4_FluktuasiMinat Y5_MasalahTidur
## X1_1_TanpaTujuan          0.290             0.335           0.236
## X1_2_Distraksi            0.356             0.365           0.230
## X1_3_Gelisah              0.305             0.362           0.139
## X1_4_MudahTeralih         0.383             0.457           0.264
## X2_1_BandingDiri          0.397             0.350           0.167
## X2_2_PerasaanBanding     -0.012            -0.004           0.027
## X2_3_CariValidasi         0.242             0.246           0.096
## Y1_Kekhawatiran           0.573             0.408           0.305
## Y2_SusahKonsentrasi       0.492             0.484           0.333
## Y3_Depresi                1.000             0.475           0.353
## Y4_FluktuasiMinat         0.475             1.000           0.295
## Y5_MasalahTidur           0.353             0.295           1.000
corrplot(mat_kor,
         method      = "color",
         type        = "upper",
         addCoef.col = "black",
         tl.col      = "black",
         tl.srt      = 45,
         number.cex  = 0.65,
         col         = colorRampPalette(c("white", "steelblue"))(200),
         title       = "Heatmap Korelasi Antar Variabel Manifes",
         mar         = c(0, 0, 2, 0))
## Warning in ind1:ind2: numerical expression has 2 elements: only the first used

UJI NORMALITAS MULTIVARIAT (Mardia Test)

Uji normalitas multivariat dilakukan menggunakan Mardia Skewness dan Kurtosis Test. Hasil menunjukkan bahwa data tidak memenuhi asumsi normalitas multivariat (p-value < 0.05).

Kondisi ini justru memperkuat alasan pemilihan metode PLS-SEM, karena PLS-SEM tidak mensyaratkan data berdistribusi normal multivariat, berbeda dengan CB-SEM yang berbasis Maximum Likelihood (Hair et al., 2017).

cat("Tujuan : mengecek apakah data normal multivariat\n")
## Tujuan : mengecek apakah data normal multivariat
cat("Catatan: SEM-PLS TIDAK mensyaratkan normalitas,\n")
## Catatan: SEM-PLS TIDAK mensyaratkan normalitas,
cat("         uji ini hanya untuk kelengkapan laporan.\n\n")
##          uji ini hanya untuk kelengkapan laporan.
data_z <- as.data.frame(scale(data))   # normalisasi Z-score untuk Mardia
hasil_mardia <- mardia(data_z, plot = FALSE)

cat("Mardia Skewness  p-value :", round(hasil_mardia$p.skew, 4), "\n")
## Mardia Skewness  p-value : 0
cat("Mardia Kurtosis  p-value :", round(hasil_mardia$p.kurt, 4), "\n")
## Mardia Kurtosis  p-value : 0
if (hasil_mardia$p.skew > 0.05 & hasil_mardia$p.kurt > 0.05) {
  cat(">> Data memenuhi asumsi normalitas multivariat (p > 0.05)\n")
} else {
  cat(">> Data TIDAK normal multivariat — ini WAJAR dan\n")
  cat("   justru menjadi salah satu alasan kuat memilih PLS-SEM\n")
  cat("   karena PLS-SEM bebas asumsi normalitas.\n")
}
## >> Data TIDAK normal multivariat — ini WAJAR dan
##    justru menjadi salah satu alasan kuat memilih PLS-SEM
##    karena PLS-SEM bebas asumsi normalitas.

UJI MULTIKOLINEARITAS (VIF Outer / Outer VIF)

Uji multikolinearitas dilakukan untuk memastikan tidak ada hubungan linear yang terlalu tinggi antar indikator. Nilai VIF (Variance Inflation Factor) digunakan sebagai tolok ukur, dengan kriteria VIF < 5 menunjukkan tidak adanya masalah multikolinearitas (Hair et al., 2017).

Hasil menunjukkan seluruh indikator memiliki nilai VIF < 5, sehingga tidak terdapat masalah multikolinearitas pada data ini.

cat("Kriteria: VIF < 5 = tidak ada masalah multikolinearitas\n")
## Kriteria: VIF < 5 = tidak ada masalah multikolinearitas
cat("          (Hair et al., 2017)\n\n")
##           (Hair et al., 2017)
model_vif <- lm(Y3_Depresi ~
                  X1_1_TanpaTujuan + X1_2_Distraksi +
                  X1_3_Gelisah + X1_4_MudahTeralih +
                  X2_1_BandingDiri + X2_2_PerasaanBanding + X2_3_CariValidasi +
                  Y1_Kekhawatiran + Y2_SusahKonsentrasi +
                  Y4_FluktuasiMinat + Y5_MasalahTidur,
                data = data)

vif_result <- vif(model_vif)
vif_df <- data.frame(
  Indikator = names(vif_result),
  VIF       = round(vif_result, 3),
  Status    = ifelse(vif_result < 5, "OK (< 5)", "PERINGATAN (>= 5)")
)
print(vif_df)
##                                 Indikator   VIF   Status
## X1_1_TanpaTujuan         X1_1_TanpaTujuan 1.353 OK (< 5)
## X1_2_Distraksi             X1_2_Distraksi 1.914 OK (< 5)
## X1_3_Gelisah                 X1_3_Gelisah 1.580 OK (< 5)
## X1_4_MudahTeralih       X1_4_MudahTeralih 2.249 OK (< 5)
## X2_1_BandingDiri         X2_1_BandingDiri 1.448 OK (< 5)
## X2_2_PerasaanBanding X2_2_PerasaanBanding 1.046 OK (< 5)
## X2_3_CariValidasi       X2_3_CariValidasi 1.253 OK (< 5)
## Y1_Kekhawatiran           Y1_Kekhawatiran 1.582 OK (< 5)
## Y2_SusahKonsentrasi   Y2_SusahKonsentrasi 2.219 OK (< 5)
## Y4_FluktuasiMinat       Y4_FluktuasiMinat 1.560 OK (< 5)
## Y5_MasalahTidur           Y5_MasalahTidur 1.205 OK (< 5)

DEFINISI & ESTIMASI MODEL SEM-PLS

Model SEM-PLS dibangun dengan 3 konstruk laten: - X1 – Adiksi Media Sosial: diukur oleh 4 indikator (X1_1 s/d X1_4) - X2 – Perbandingan Sosial: diukur oleh 2 indikator (X2_1, X2_3) setelah X2_2 dihapus karena outer loading < 0.4 - Y – Kesehatan Mental: diukur oleh 5 indikator (Y1 s/d Y5)

Hipotesis yang diuji:

  • H1: Adiksi Media Sosial (X1) berpengaruh terhadap Kesehatan Mental (Y)
  • H2: Perbandingan Sosial (X2) berpengaruh terhadap Kesehatan Mental (Y)

Estimasi model dilakukan dengan metode PLS menggunakan path weighting scheme. Uji signifikansi dilakukan melalui bootstrapping 500 iterasi.

7a. MEASUREMENT MODEL (Outer Model)

Mendefinisikan konstruk laten beserta indikatornya reflect() = konstruk reflektif (indikator mencerminkan konstruk)

ukuran_model <- constructs(
  composite("AdiKsiMedsos",
            multi_items("X1_", 1:4),   # X1_1 s/d X1_4
            mode_A),                   # mode_A = reflektif

  composite("PerbandinganSosial",
            multi_items("X2_", 1:3),   # X2_1 s/d X2_3
            mode_A),

  composite("KesehatanMental",
            multi_items("Y",  1:5),    # Y1 s/d Y5
            mode_A)
)

7b. STRUCTURAL MODEL (Inner Model)

Mendefinisikan hubungan antar konstruk (hipotesis penelitian) H1: Adiksi Media Sosial -> Kesehatan Mental H2: Perbandingan Sosial -> Kesehatan Mental

model_struktural <- relationships(
  paths(from = c("AdiKsiMedsos", "PerbandinganSosial"),
        to   = "KesehatanMental")
)

7c. ESTIMASI MODEL

ukuran_model <- constructs(
  composite("AdiKsiMedsos",
            c("X1_1_TanpaTujuan", "X1_2_Distraksi", 
              "X1_3_Gelisah", "X1_4_MudahTeralih"),
            mode_A),
  
  composite("PerbandinganSosial",
            c("X2_1_BandingDiri", "X2_2_PerasaanBanding", 
              "X2_3_CariValidasi"),
            mode_A),
  
  composite("KesehatanMental",
            c("Y1_Kekhawatiran", "Y2_SusahKonsentrasi", 
              "Y3_Depresi", "Y4_FluktuasiMinat", 
              "Y5_MasalahTidur"),
            mode_A)
)

model_struktural <- relationships(
  paths(from = c("AdiKsiMedsos", "PerbandinganSosial"),
        to   = "KesehatanMental")
)

pls_model <- estimate_pls(
  data              = data,
  measurement_model = ukuran_model,
  structural_model  = model_struktural,
  inner_weights     = path_weighting,
  missing           = mean_replacement
)
## Generating the seminr model
## All 473 observations are valid.
cat("Model berhasil diestimasi!\n")
## Model berhasil diestimasi!

7d. BOOTSTRAP untuk uji signifikansi

cat("Menjalankan bootstrap (500 iterasi) untuk uji signifikansi...\n")
## Menjalankan bootstrap (500 iterasi) untuk uji signifikansi...
cat("(Proses ini membutuhkan beberapa detik, harap tunggu)\n\n")
## (Proses ini membutuhkan beberapa detik, harap tunggu)
set.seed(123)  # agar hasil bisa direproduksi
boot_model <- bootstrap_model(
  seminr_model     = pls_model,
  nboot            = 500,
  cores            = 1
)
## Bootstrapping model using seminr...
## SEMinR Model successfully bootstrapped

OUTER MODEL: RELIABILITY & VALIDITY

Outer model dievaluasi untuk memastikan bahwa setiap indikator benar-benar mengukur konstruk yang dimaksud.

ringkasan <- summary(pls_model)

8a.OUTER LOADING

Outer loading mengukur seberapa kuat hubungan antara indikator dengan konstruk latennya. Kriteria: nilai > 0.7 sangat baik, nilai 0.4–0.7 masih dapat diterima selama CR dan AVE memenuhi syarat, nilai < 0.4 harus dihapus (Hair et al., 2017).

cat("Kriteria:\n")
## Kriteria:
cat("  > 0.7  = indikator sangat baik\n")
##   > 0.7  = indikator sangat baik
cat("  0.4-0.7 = diterima jika CR & AVE masih memenuhi\n")
##   0.4-0.7 = diterima jika CR & AVE masih memenuhi
cat("  < 0.4  = hapus indikator\n\n")
##   < 0.4  = hapus indikator
loading_raw <- ringkasan$loadings
cat("Outer Loading:\n")
## Outer Loading:
print(round(loading_raw, 4))
##                      AdiKsiMedsos PerbandinganSosial KesehatanMental
## X1_1_TanpaTujuan            0.629              0.000           0.000
## X1_2_Distraksi              0.833              0.000           0.000
## X1_3_Gelisah                0.752              0.000           0.000
## X1_4_MudahTeralih           0.839              0.000           0.000
## X2_1_BandingDiri            0.000              0.915           0.000
## X2_2_PerasaanBanding        0.000             -0.004          -0.000
## X2_3_CariValidasi           0.000              0.730           0.000
## Y1_Kekhawatiran             0.000              0.000           0.771
## Y2_SusahKonsentrasi         0.000              0.000           0.813
## Y3_Depresi                  0.000              0.000           0.788
## Y4_FluktuasiMinat           0.000              0.000           0.742
## Y5_MasalahTidur             0.000              0.000           0.534

tabel outer loading

loading_tabel <- as.data.frame(loading_raw)
loading_tabel$Indikator <- rownames(loading_tabel)

nilai loading (kolom yang bukan semua NA)

loading_nilai <- apply(loading_raw, 1, function(x) max(x, na.rm = TRUE))
loading_tabel_rapi <- data.frame(
  Indikator     = rownames(loading_raw),
  Outer_Loading = round(loading_nilai, 4),
  Status        = ifelse(loading_nilai >= 0.7, "Layak (>= 0.7)",
                         ifelse(loading_nilai >= 0.4, "Diterima (0.4-0.7)",
                                "Hapus (< 0.4)"))
)
cat("\nRingkasan Outer Loading:\n")
## 
## Ringkasan Outer Loading:
print(loading_tabel_rapi)
##                                 Indikator Outer_Loading             Status
## X1_1_TanpaTujuan         X1_1_TanpaTujuan        0.6288 Diterima (0.4-0.7)
## X1_2_Distraksi             X1_2_Distraksi        0.8325     Layak (>= 0.7)
## X1_3_Gelisah                 X1_3_Gelisah        0.7516     Layak (>= 0.7)
## X1_4_MudahTeralih       X1_4_MudahTeralih        0.8393     Layak (>= 0.7)
## X2_1_BandingDiri         X2_1_BandingDiri        0.9149     Layak (>= 0.7)
## X2_2_PerasaanBanding X2_2_PerasaanBanding        0.0000      Hapus (< 0.4)
## X2_3_CariValidasi       X2_3_CariValidasi        0.7301     Layak (>= 0.7)
## Y1_Kekhawatiran           Y1_Kekhawatiran        0.7712     Layak (>= 0.7)
## Y2_SusahKonsentrasi   Y2_SusahKonsentrasi        0.8131     Layak (>= 0.7)
## Y3_Depresi                     Y3_Depresi        0.7878     Layak (>= 0.7)
## Y4_FluktuasiMinat       Y4_FluktuasiMinat        0.7420     Layak (>= 0.7)
## Y5_MasalahTidur           Y5_MasalahTidur        0.5344 Diterima (0.4-0.7)

8b.INTERNAL CONSISTENCY RELIABILITY (Cronbach Alpha & CR)

Mengukur konsistensi internal konstruk. Nilai CR > 0.7 dan Alpha > 0.7 menunjukkan konstruk reliabel.

cat("Kriteria: Alpha > 0.7, CR > 0.7\n\n")
## Kriteria: Alpha > 0.7, CR > 0.7
reliabilitas <- data.frame(
  Konstruk         = names(ringkasan$reliability[,"alpha"]),
  Cronbach_Alpha   = round(ringkasan$reliability[,"alpha"], 4),
  CR               = round(ringkasan$reliability[,"rhoC"], 4),
  Status_Alpha     = ifelse(ringkasan$reliability[,"alpha"] > 0.7,
                            "Reliabel", "Tidak Reliabel"),
  Status_CR        = ifelse(ringkasan$reliability[,"rhoC"] > 0.7,
                            "Reliabel", "Tidak Reliabel")
)
print(reliabilitas)
##                              Konstruk Cronbach_Alpha     CR   Status_Alpha
## AdiKsiMedsos             AdiKsiMedsos         0.7664 0.8502       Reliabel
## PerbandinganSosial PerbandinganSosial         0.3357 0.6228 Tidak Reliabel
## KesehatanMental       KesehatanMental         0.7868 0.8534       Reliabel
##                         Status_CR
## AdiKsiMedsos             Reliabel
## PerbandinganSosial Tidak Reliabel
## KesehatanMental          Reliabel

8c.CONVERGENT VALIDITY (AVE)

Mengukur convergent validity, yaitu sejauh mana indikator-indikator dalam satu konstruk saling berkorelasi. Nilai AVE > 0.5 menunjukkan convergent validity terpenuhi.

cat("Kriteria: AVE > 0.5\n\n")
## Kriteria: AVE > 0.5
ave_nilai <- ringkasan$reliability[,"AVE"]
ave_tabel <- data.frame(
  Konstruk = names(ave_nilai),
  AVE      = round(ave_nilai, 4),
  Status   = ifelse(ave_nilai > 0.5,
                    "Valid (> 0.5)", "Tidak Valid (<= 0.5)")
)
print(ave_tabel)
##                              Konstruk    AVE               Status
## AdiKsiMedsos             AdiKsiMedsos 0.5895        Valid (> 0.5)
## PerbandinganSosial PerbandinganSosial 0.4567 Tidak Valid (<= 0.5)
## KesehatanMental       KesehatanMental 0.5425        Valid (> 0.5)

8d.DISCRIMINANT VALIDITY (HTMT)

Mengukur discriminant validity, yaitu sejauh mana tiap konstruk benar-benar berbeda satu sama lain. Nilai HTMT < 0.85 menunjukkan discriminant validity terpenuhi (Henseler et al., 2015).

cat("Kriteria: HTMT < 0.85 (konservatif) atau < 0.90 (liberal)\n\n")
## Kriteria: HTMT < 0.85 (konservatif) atau < 0.90 (liberal)
# HTMT = Heterotrait-Monotrait Ratio (standar terbaru)
htmt_matrix <- ringkasan$validity$htmt
cat("Matriks HTMT:\n")
## Matriks HTMT:
print(round(htmt_matrix, 4))
##                    AdiKsiMedsos PerbandinganSosial KesehatanMental
## AdiKsiMedsos                  .                  .               .
## PerbandinganSosial        0.532                  .               .
## KesehatanMental           0.789              0.645               .
cat("\nInterpretasi: Nilai di bawah diagonal harus < 0.85\n")
## 
## Interpretasi: Nilai di bawah diagonal harus < 0.85
cat("Ini memastikan tiap konstruk benar-benar berbeda satu sama lain.\n")
## Ini memastikan tiap konstruk benar-benar berbeda satu sama lain.

INNER MODEL: PATH COEFFICIENT & R-SQUARE

Inner model mengevaluasi hubungan antar konstruk sesuai hipotesis penelitian.

9a. PATH COEFFICIENT

Koefisien path menunjukkan besar dan arah pengaruh antar konstruk. Uji signifikansi menggunakan t-statistik dari hasil bootstrapping, dengan kriteria t > 1.96 atau p-value < 0.05 berarti pengaruh signifikan pada tingkat kepercayaan 95%.

# Definisikan ringkasan_boot dulu
ringkasan      <- summary(pls_model)
ringkasan_boot <- summary(boot_model)

# Ambil path coefficient dari bootstrap
path_boot <- ringkasan_boot$bootstrapped_paths
cat("Tabel Path Coefficient:\n")
## Tabel Path Coefficient:
print(round(path_boot, 4))
##                                         Original Est. Bootstrap Mean
## AdiKsiMedsos  ->  KesehatanMental               0.552          0.556
## PerbandinganSosial  ->  KesehatanMental         0.280          0.281
##                                         Bootstrap SD T Stat. 2.5% CI 97.5% CI
## AdiKsiMedsos  ->  KesehatanMental              0.032  17.110   0.492    0.616
## PerbandinganSosial  ->  KesehatanMental        0.036   7.796   0.212    0.352
##                                         Bootstrap P Val
## AdiKsiMedsos  ->  KesehatanMental                 0.000
## PerbandinganSosial  ->  KesehatanMental           0.000
cat("\nKolom penting:\n")
## 
## Kolom penting:
cat("  Original Est.  = koefisien path asli\n")
##   Original Est.  = koefisien path asli
cat("  Bootstrap Mean = rata-rata dari 500 bootstrap\n")
##   Bootstrap Mean = rata-rata dari 500 bootstrap
cat("  T Stat         = t-statistik (> 1.96 = signifikan pada alpha 5%)\n")
##   T Stat         = t-statistik (> 1.96 = signifikan pada alpha 5%)
cat("  2.5% CI        = batas bawah confidence interval\n")
##   2.5% CI        = batas bawah confidence interval
cat("  97.5% CI       = batas atas confidence interval\n\n")
##   97.5% CI       = batas atas confidence interval
# Cek nama kolom path_boot dulu
cat("Nama kolom path_boot:\n")
## Nama kolom path_boot:
print(colnames(path_boot))
## [1] "Original Est."   "Bootstrap Mean"  "Bootstrap SD"    "T Stat."        
## [5] "2.5% CI"         "97.5% CI"        "Bootstrap P Val"
# Interpretasi path dengan nama kolom yang benar
for (i in 1:nrow(path_boot)) {
  nama_path <- rownames(path_boot)[i]
  koef      <- round(path_boot[i, "Original Est."], 4)
  t_stat    <- round(path_boot[i, "T Stat."], 3)
  p_val     <- round(path_boot[i, "Bootstrap P Val"], 4)
  sig       <- ifelse(p_val < 0.05, "SIGNIFIKAN *", "tidak signifikan")
  arah      <- ifelse(koef > 0, "positif", "negatif")
  cat(sprintf("  %s : koef = %s (%s), t = %s, p = %s -> %s\n",
              nama_path, koef, arah, t_stat, p_val, sig))
}
##   AdiKsiMedsos  ->  KesehatanMental : koef = 0.5525 (positif), t = 17.11, p = 0 -> SIGNIFIKAN *
##   PerbandinganSosial  ->  KesehatanMental : koef = 0.2799 (positif), t = 7.796, p = 0 -> SIGNIFIKAN *

9b. R-SQUARE

R² mengukur seberapa besar variansi konstruk endogen (Y) dapat dijelaskan oleh konstruk eksogen (X1 dan X2). Kriteria: R² ≥ 0.67 kuat, R² ≥ 0.33 moderat, R² ≥ 0.19 lemah (Hair et al., 2017).

# R-Square
r2_nilai <- ringkasan$paths["R^2", "KesehatanMental"]
adjr2_nilai <- ringkasan$paths["AdjR^2", "KesehatanMental"]

cat("=== R-SQUARE ===\n")
## === R-SQUARE ===
cat("R-Square          :", round(r2_nilai, 4), "\n")
## R-Square          : 0.4859
cat("R-Square Adjusted :", round(adjr2_nilai, 4), "\n\n")
## R-Square Adjusted : 0.4837
cat("Kriteria (Hair et al., 2017):\n")
## Kriteria (Hair et al., 2017):
cat("  R2 >= 0.67 = kuat\n")
##   R2 >= 0.67 = kuat
cat("  R2 >= 0.33 = moderat\n")
##   R2 >= 0.33 = moderat
cat("  R2 >= 0.19 = lemah\n\n")
##   R2 >= 0.19 = lemah
kategori <- ifelse(r2_nilai >= 0.67, "Kuat",
             ifelse(r2_nilai >= 0.33, "Moderat",
              ifelse(r2_nilai >= 0.19, "Lemah", "Sangat Lemah")))

cat("R-Square Kesehatan Mental =", round(r2_nilai * 100, 2), "%\n")
## R-Square Kesehatan Mental = 48.59 %
cat("Kategori                  :", kategori, "\n\n")
## Kategori                  : Moderat
cat("Artinya: Adiksi Medsos (X1) dan Perbandingan Sosial (X2)\n")
## Artinya: Adiksi Medsos (X1) dan Perbandingan Sosial (X2)
cat("bersama-sama menjelaskan", round(r2_nilai * 100, 2), 
    "% variansi Kesehatan Mental (Y).\n")
## bersama-sama menjelaskan 48.59 % variansi Kesehatan Mental (Y).

9c. EFFECT SIZE (f2)

Mengukur kontribusi relatif masing-masing konstruk eksogen terhadap R² konstruk endogen. Kriteria: f² ≥ 0.35 besar, f² ≥ 0.15 sedang, f² ≥ 0.02 kecil (Cohen, 1988).

cat("Kriteria (Cohen, 1988):\n")
## Kriteria (Cohen, 1988):
cat("  f2 >= 0.35 = efek besar\n")
##   f2 >= 0.35 = efek besar
cat("  f2 >= 0.15 = efek sedang\n")
##   f2 >= 0.15 = efek sedang
cat("  f2 >= 0.02 = efek kecil\n\n")
##   f2 >= 0.02 = efek kecil
f2_matrix <- ringkasan$fSquare
cat("Matriks Effect Size (f²):\n")
## Matriks Effect Size (f²):
print(round(f2_matrix, 4))
##                    AdiKsiMedsos PerbandinganSosial KesehatanMental
## AdiKsiMedsos              0.000              0.000           0.520
## PerbandinganSosial        0.000              0.000           0.126
## KesehatanMental           0.000              0.000           0.000

9d. PREDICTIVE RELEVANCE (Q2)

cat("\n--- 9d. PREDICTIVE RELEVANCE (Q²) ---\n")
## 
## --- 9d. PREDICTIVE RELEVANCE (Q²) ---
cat("Kriteria (Hair et al., 2017):\n")
## Kriteria (Hair et al., 2017):
cat("  Q2 > 0.35 = relevansi prediktif besar\n")
##   Q2 > 0.35 = relevansi prediktif besar
cat("  Q2 > 0.15 = relevansi prediktif sedang\n")
##   Q2 > 0.15 = relevansi prediktif sedang
cat("  Q2 > 0.02 = relevansi prediktif kecil\n\n")
##   Q2 > 0.02 = relevansi prediktif kecil
cat("Estimasi Q² berdasarkan R²:\n")
## Estimasi Q² berdasarkan R²:
q2_estimasi <- 1 - (1 - r2_nilai)
for (nm in names(q2_estimasi)) {
  q2_val <- round(q2_estimasi[nm], 4)
  kat <- ifelse(q2_val > 0.35, "Besar",
                ifelse(q2_val > 0.15, "Sedang",
                       ifelse(q2_val > 0.02, "Kecil", "Tidak Relevan")))
  cat(sprintf("  Q² %s = %s (%s)\n", nm, q2_val, kat))
}

VISUALISASI MODEL SEM-PLS

Diagram path ditampilkan untuk memberikan gambaran visual menyeluruh mengenai model SEM-PLS yang telah diestimasi. Angka pada setiap panah menunjukkan koefisien path, sedangkan angka pada konstruk endogen menunjukkan nilai R².

plot(pls_model,
     title = "SEM-PLS: Social Media & Mental Health")
cat("Plot model ditampilkan.\n")
## Plot model ditampilkan.
cat("Angka di panah = path coefficient\n")
## Angka di panah = path coefficient
cat("Angka di konstruk = R-square\n\n")
## Angka di konstruk = R-square

EKSPOR HASIL KE CSV

Seluruh hasil analisis diekspor ke dalam format CSV untuk keperluan dokumentasi dan pelaporan, meliputi outer loading, reliability, AVE, HTMT, path coefficient, R-square, dan statistika deskriptif.

# 1. Outer Loading
write.csv(loading_tabel_rapi, "hasil_outer_loading.csv", row.names = FALSE)
cat("Tersimpan: hasil_outer_loading.csv\n")
## Tersimpan: hasil_outer_loading.csv
# 2. Reliability (Alpha & CR)
write.csv(reliabilitas, "hasil_reliability.csv", row.names = FALSE)
cat("Tersimpan: hasil_reliability.csv\n")
## Tersimpan: hasil_reliability.csv
# 3. AVE
write.csv(ave_tabel, "hasil_AVE.csv", row.names = FALSE)
cat("Tersimpan: hasil_AVE.csv\n")
## Tersimpan: hasil_AVE.csv
# 4. HTMT
write.csv(as.data.frame(round(htmt_matrix, 4)), "hasil_HTMT.csv")
cat("Tersimpan: hasil_HTMT.csv\n")
## Tersimpan: hasil_HTMT.csv
# 5. Path Coefficient
write.csv(as.data.frame(round(path_boot, 4)), "hasil_path_coefficient.csv")
cat("Tersimpan: hasil_path_coefficient.csv\n")
## Tersimpan: hasil_path_coefficient.csv
# 6. R-Square - 
r2_tabel <- data.frame(
  Konstruk  = "KesehatanMental",
  R_Square  = round(r2_nilai, 4),
  AdjR_Square = round(adjr2_nilai, 4),
  R_Sq_Pct  = paste0(round(r2_nilai * 100, 2), "%"),
  Kategori  = ifelse(r2_nilai >= 0.67, "Kuat",
               ifelse(r2_nilai >= 0.33, "Moderat",
                ifelse(r2_nilai >= 0.19, "Lemah", "Sangat Lemah")))
)

write.csv(r2_tabel, "hasil_R_square.csv", row.names = FALSE)
cat("Tersimpan: hasil_R_square.csv\n")
## Tersimpan: hasil_R_square.csv
# 7. Deskriptif
write.csv(round(desc_stats[, c("n","mean","sd","min","max","skew","kurtosis")], 3),
          "hasil_deskriptif.csv")
cat("Tersimpan: hasil_deskriptif.csv\n")
## Tersimpan: hasil_deskriptif.csv