Introduction to PLSsemEngine

Manuel Soto Pérez

Professional PLS-SEM Workflow with PLSsemEngine

This vignette demonstrates how to estimate a reflective PLS-SEM model using PLSsemEngine. The package provides a transparent and modular workflow for composite-based Mode A estimation.

1. Data Generation

To demonstrate the workflow, we first generate a synthetic dataset (N = 300) with a typical Service Marketing structure.

library(PLSsemEngine)
set.seed(123)

# Helper function for data simulation
simulate_example_data <- function(n) {
  Service_Quality <- rnorm(n)
  Customer_Satisfaction <- 0.6 * Service_Quality + rnorm(n, sd = 0.6)
  Customer_Loyalty <- 0.55 * Customer_Satisfaction + 0.25 * Service_Quality + rnorm(n, sd = 0.6)
  
  latent_to_item <- function(latent, loading) {
    x <- loading * latent + rnorm(length(latent), sd = sqrt(1 - loading^2))
    x <- scale(x)
    as.numeric(cut(x, breaks = quantile(x, probs = seq(0, 1, length.out = 8)), 
                   labels = 1:7, include.lowest = TRUE))
  }
  
  data.frame(
    SQ1 = latent_to_item(Service_Quality, 0.82), SQ2 = latent_to_item(Service_Quality, 0.78), SQ3 = latent_to_item(Service_Quality, 0.74),
    CS1 = latent_to_item(Customer_Satisfaction, 0.80), CS2 = latent_to_item(Customer_Satisfaction, 0.76), CS3 = latent_to_item(Customer_Satisfaction, 0.72),
    CL1 = latent_to_item(Customer_Loyalty, 0.81), CL2 = latent_to_item(Customer_Loyalty, 0.77), CL3 = latent_to_item(Customer_Loyalty, 0.73)
  )
}

simulated_data <- simulate_example_data(300)

2. Model Specification

The engine uses native R structures (lists and formulas) to define the model.

# Define reflective blocks
measurement_model <- list(
  Service_Quality = c("SQ1", "SQ2", "SQ3"),
  Customer_Satisfaction = c("CS1", "CS2", "CS3"),
  Customer_Loyalty = c("CL1", "CL2", "CL3")
)

# Define structural paths using formulas
structural_model <- list(
  Customer_Satisfaction ~ Service_Quality,
  Customer_Loyalty ~ Customer_Satisfaction + Service_Quality
)

3. Execution

The pls_sem() function executes the core algorithm, bootstrap, and predictive evaluation.

model <- pls_sem(
  data = simulated_data,
  measurement_model = measurement_model,
  structural_model = structural_model,
  nboot = 100, # Using 100 for speed in this vignette
  k = 5
)
#> Warning: Negative Q2_predict detected: PLS-based predictions are outperformed
#> by the linear benchmark, indicating low predictive relevance (Shmueli et al.,
#> 2019).

4. Results Inspection

The results are organized into descriptive tables that match the manuscript’s structure.

# Measurement Model
model$measurement_model
#>               Construct Item Loading Composite Reliability (CR)  AVE   R2
#> 1      Customer_Loyalty  CL1    0.81                       0.85 0.65 0.32
#> 2      Customer_Loyalty  CL2    0.79                       0.85 0.65 0.32
#> 3      Customer_Loyalty  CL3    0.82                       0.85 0.65 0.32
#> 4 Customer_Satisfaction  CS1    0.83                       0.84 0.64 0.26
#> 5 Customer_Satisfaction  CS2    0.79                       0.84 0.64 0.26
#> 6 Customer_Satisfaction  CS3    0.77                       0.84 0.64 0.26
#> 7       Service_Quality  SQ1    0.88                       0.87 0.69   NA
#> 8       Service_Quality  SQ2    0.83                       0.87 0.69   NA
#> 9       Service_Quality  SQ3    0.78                       0.87 0.69   NA

# Discriminant Validity
model$discriminant_validity
#> $HTMT
#>                       Service_Quality Customer_Satisfaction Customer_Loyalty
#> Service_Quality                    NA                  0.68             0.62
#> Customer_Satisfaction            0.68                    NA             0.70
#> Customer_Loyalty                 0.62                  0.70               NA
#> 
#> $HTMT2
#>                       Service_Quality Customer_Satisfaction Customer_Loyalty
#> Service_Quality                    NA                  0.67             0.62
#> Customer_Satisfaction            0.67                    NA             0.70
#> Customer_Loyalty                 0.62                  0.70               NA

# Structural Model
model$structural_model
#>                    From                    To Path Coefficient (beta) CI_low
#> 1       Service_Quality Customer_Satisfaction                    0.51   0.43
#> 2 Customer_Satisfaction      Customer_Loyalty                    0.36   0.27
#> 3       Service_Quality      Customer_Loyalty                    0.28   0.17
#>   CI_high   f2
#> 1    0.58 0.35
#> 2    0.46 0.14
#> 3    0.39 0.09

5. Interpretation

Factor loadings above 0.70 indicate acceptable indicator reliability. Structural path coefficients can be interpreted as standardized effects between constructs.

6. Advanced Features

To address reviewer feedback, we include global fit indices and a bridge to CB-SEM.

# Global Model Fit (SRMR, d_ULS, d_G)
model$diagnostics$global_fit
#>   Metric Value
#> 1   SRMR  0.09
#> 2  d_ULS  0.29
#> 3    d_G  0.63

# Export to lavaan syntax
export_lavaan_syntax(measurement_model, structural_model)
#> 
#> =================================================================
#>  LAVAAN SYNTAX GENERATOR (CB-SEM / CFA Integration)
#>  Copy and paste this syntax to run models using the 'lavaan' package.
#> =================================================================
#> 
#> # --- Measurement Model (CFA) ---
#> Service_Quality =~ SQ1 + SQ2 + SQ3
#> Customer_Satisfaction =~ CS1 + CS2 + CS3
#> Customer_Loyalty =~ CL1 + CL2 + CL3
#> 
#> # --- Structural Model ---
#> Customer_Satisfaction ~ Service_Quality
#> Customer_Loyalty ~ Customer_Satisfaction + Service_Quality 
#> 
#> =================================================================