# Install the SEMinR package
install.packages(pkgs = "seminr")
# Install the textbook packages from CRAN
install.packages(pkgs = c("learnr", "paran", "psych", "seminrExtras"))Partial Least Squares Structural Equation Modeling (PLS-SEM) Using R
Concise R Code and Outputs
1 Introduction
This document accompanies the book Partial Least Squares Structural Equation Modeling (PLS-SEM) Using R by Joseph F. Hair, Jr., Tomas M. Hult, Christian M. Ringle, Marko Sarstedt, Nicholas P. Danks, and Susanne J. Adler.
This document introduces a concise version of the book’s R Code and outputs for the example corporate reputation model.
Due to the concise nature of this document, we omit Chapters 1 and 2 in this document and refer readers to the book for detailed explanations of the R code and outputs.
demo(“seminr-primer-v2-chap5”)
2 Chapter 1 and 2:
Please note that seminr must be version 2.4.0 or higher and seminrExtras must be 0.9.0 or higher for this tutorial.
3 Chapter 3: Introduction to SEMinR
3.1 Installing and loading the package
Download the packages SEMinR (Ray et al., 2025) and seminrExtras (Ray & Danks, 2025) by calling install.packages("seminr") and install.packages("seminrExtras") (You only need to do this once to equip RStudio on your computer with SEMinR.)
Load both packages with library(seminr) and library(seminrExtras). (You must do this everytime you restart RStudio and wish to use SEMinR.)
# Download and install the SEMinR package
# You only need to do this once to equip RStudio with SEMinR and seminrExtras
install.packages("seminr")
install.packages("seminrExtras")# Make the SEMinR library ready to use
# You must do this every time you restart RStudio and wish to use packages
library(seminr)
library(seminrExtras)3.2 Loading the data
We will use the corporate reputation data set () for this example.
Load the corporate reputation data set from the CSV file “Corporate Reputation Data.csv” into RStudio using the read.csv() function. You must first download the data file from the book’s companion website and save it to your working directory.
# Load the corporate reputation data
corp_rep_data <- read.csv(file = "Corporate Reputation Data.csv",
header = TRUE, sep = ";")Inspect the first six rows of the data set using the head() function.
head(corp_rep_data)| serviceprovider | servicetype | comp_1 | comp_2 | comp_3 | like_1 | like_2 | like_3 | cusl_1 | cusl_2 | cusl_3 | cusa | csor_1 | csor_2 | csor_3 | csor_4 | csor_5 | csor_global | attr_1 | attr_2 | attr_3 | attr_global | perf_1 | perf_2 | perf_3 | perf_4 | perf_5 | perf_global | qual_1 | qual_2 | qual_3 | qual_4 | qual_5 | qual_6 | qual_7 | qual_8 | qual_global | switch_1 | switch_2 | switch_3 | switch_4 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 3 | 2 | 4 | 5 | 5 | 3 | 1 | 2 | 5 | 3 | 3 | 5 | 3 | 3 | 3 | 3 | 3 | 3 | 5 | 1 | 3 | 5 | 5 | 4 | 2 | 5 | 6 | 6 | 5 | 6 | 4 | 2 | 4 | 4 | 2 | 5 | 6 | 3 | 1 | 3 | 2 |
| 3 | 2 | 6 | 7 | 6 | 6 | 6 | 6 | 7 | 7 | 7 | 7 | 2 | 5 | 6 | 4 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 5 | 6 | 6 | 5 | 6 | 5 | 5 | 4 | 4 |
| 3 | 2 | 4 | 5 | 2 | 5 | 5 | 5 | 7 | 7 | 5 | 6 | 3 | 1 | 2 | 2 | 4 | 4 | 5 | 6 | 5 | 6 | 4 | 4 | 2 | 5 | 4 | 5 | 3 | 4 | 3 | 4 | 3 | 5 | 4 | 4 | 5 | 4 | 3 | 2 | 3 |
| 3 | 2 | 6 | 4 | 4 | 6 | 5 | 6 | 7 | 7 | 7 | 6 | 3 | 3 | 5 | 3 | 5 | 5 | 3 | 7 | 5 | 7 | 5 | 5 | 5 | 3 | 6 | 6 | 5 | 6 | 6 | 7 | 5 | 4 | 5 | 6 | 7 | 3 | 4 | 4 | 2 |
| 3 | 2 | 6 | 4 | 6 | 6 | 6 | 7 | 6 | 7 | 7 | 6 | 4 | 3 | 4 | 4 | 4 | 4 | 6 | 6 | 6 | 6 | 5 | 6 | 7 | 6 | 5 | 7 | 6 | 5 | 7 | 7 | 6 | 6 | 6 | 7 | 7 | 5 | 5 | 5 | 4 |
| 3 | 2 | 3 | 4 | 4 | 6 | 7 | 7 | 7 | 7 | 7 | 6 | 3 | 3 | 4 | 3 | 3 | 4 | 4 | 1 | 5 | 5 | 6 | 6 | 4 | 5 | 6 | 6 | 5 | 5 | 5 | 6 | 5 | 6 | 3 | 4 | 6 | 5 | 2 | 4 | 4 |
3.3 Specifying the measurement model
Use the below code to create the measurement model for the simple corporate reputation model (Hair et al., 2026). Figure 1 shows the simple corporate reputation model and Table 1 provides details on the measurement items.
| construct | variable name | item |
|---|---|---|
| Competence (COMP) | comp_1 | [The company] is a top competitor in its market. |
| Competence (COMP) | comp_2 | As far as I know, [the company] is recognized worldwide. |
| Competence (COMP) | comp_3 | I believe that [the company] performs at a premium level. |
| Likeability (LIKE) | like_1 | [The company] is a company that I can better identify with than other companies. |
| Likeability (LIKE) | like_2 | [The company] is a company that I would regret more not having if it no longer existed than I would other companies. |
| Likeability (LIKE) | like_3 | I regard [the company] as a likeable company. |
| Customer Satisfaction (CUSA) | cusa | I am satisfied with [the company]. |
| Customer Loyalty (CUSL) | cusl_1 | I would recommend [company] to friends and relatives. |
| Customer Loyalty (CUSL) | cusl_2 | If I had to choose again, I would choose [company] as my mobile phone services provider. |
| Customer Loyalty (CUSL) | cusl_3 | I will remain a customer of [company] in the future. |
In the code provided below, we create four constructs: COMP (composite with three indicators), LIKE (composite with three indicators), CUSA (single-item composite), and CUSL (composite with three indicators).
The constructs() function specifies the list of all construct measurement models. Within this list you can define various constructs:
composite()specifies the measurement of individual constructs.interaction_term()specifies interactions terms.higher_composite()specifies hierarchical component models, i.e. higher-order constructs (Sarstedt et al., 2019).
Thereby, composite() specifies the measurement of individual constructs and
multi_items()creates a vector of multiple measurement items with similar names.single_item()describe a single measurement item.
For example, the composite COMP incorporates the items comp_1 to comp_3.
We save the output to the simple_mm element.
# Create measurement model ----
simple_mm <- constructs(
composite("COMP", multi_items("comp_", 1:3)),
composite("LIKE", multi_items("like_", 1:3)),
composite("CUSA", single_item("cusa")),
composite("CUSL", multi_items("cusl_", 1:3)))The measuremnt model specification above is equivalent to specifying composite("COMP", multi_items("comp_", 1:3), weights = mode_A). That is because, weights = mode_A is the default in SEMinR and thus does not need to be specified explicitly.
In principle, SEMinR provides two modes for measurement model estimation. The setup of the measurement model depends on whether the construct under consideration is modeled reflectively or formatively.
For reflective measurement models, we use mode A. The mode A estimation produces indicator loadings that correspond to bivariate correlations between the construct and its associated indicators (i.e., correlation weights).
For formative measurement models, we use mode B. The mode B estimation produces indicator weights that correspond to regressing the construct on its associated indicators.
3.4 Specifying the structural model
The structural model indicates the sequence of the constructs and the relationships between them.
relationships()specifies all the structural relationships between all constructs.paths()specifies relationships between a specific set of antecedents and outcomes.
For example, to specify the relationships from COMP and LIKE to CUSA and CUSL, we use the from = and to = arguments in the paths() function: paths(from = c("COMP", "LIKE"), to = c("CUSA", "CUSL")).
We save the output to the simple_sm element.
# Create structural model ----
simple_sm <- relationships(
paths(from = c("COMP", "LIKE"), to = c("CUSA", "CUSL")),
paths(from = c("CUSA"), to = c("CUSL")))3.5 Estimating the model
We use estimate_pls() to estimate the PLS model.
estimate_pls() requires the following arguments: - data: The data frame containing the corporate reputation data. - measurement_model: The measurement model specified earlier simple_mm. - structural_model: The structural model specified earlier simple_sm. - inner_weights: The inner weighting scheme to be used for estimating the structural model. - missing: The missing data treatment method to be used. - missing_value: The value used in the data set to indicate missing data.
For path weighting, SEMinR has two structural model (inner) weighting schemes:
- Path weighting scheme: The most popular and recommended approach.
- Factor weighting scheme: Provides the highest R² value for endogenous latent variables.
In this example, we apply mean replacement to handle missing data (missing = mean_replacement) and specify that missing values are coded as -99 in the data set (missing_value = "-99").
# Estimate the model
corp_rep_simple_model <- estimate_pls(data = corp_rep_data,
measurement_model = simple_mm,
structural_model = simple_sm,
inner_weights = path_weighting,
missing = mean_replacement,
missing_value = "-99")Generating the seminr model
All 344 observations are valid.
Arguments with default values (e.g. inner_weights, missing, and missing_value) canalso be omitted. The code above therefore is equivalent to corp_rep_simple <- estimate_pls(data = corp_rep_data, measurement_model = simple_mm, structural_model = simple_sm)
3.6 Debugging and problem solving
SEMinR has several features which assist users in bug checking and resolution. The majority of issues tyoically arises due to incorrectly entering or specifying item and construct names such as comp_1 and COMP. To address this isseue, SEMinR provides assess_syntax within the estimate_pls() function. When assess_syntax = TRUE, the measurement and structural model will be searched for common mistakes such as misspelled constructs, incorrectly specified interaction terms, or misspelled indicator names.
This code block demonstrates a spelling error in which COMP was erronously spelled COP.
## Using the `assess_syntax` argument in `estimate_pls()`
# Specify the measurement model with a bug in the spelling of the construct
# `COMP`: Here it is `COP` and in the actual model it is `COMP`.
error_mm <- constructs(
composite("COP", multi_items("comp_", 1:3)),
composite("LIKE", multi_items("like_", 1:3)),
composite("CUSA", single_item("cusa")),
composite("CUSL", multi_items("cusl_", 1:3)))
# Specify the structural model.
simple_sm <- relationships(
paths(from = c("COMP", "LIKE"), to = c("CUSA", "CUSL")),
paths(from = c("CUSA"), to = c("CUSL")))
# Note that we have specified the argument `assess_syntax` as TRUE
# Now estimating the model should output an error
estimate_pls(data = corp_rep_data,
measurement_model = error_mm,
structural_model = simple_sm,
assess_syntax = TRUE)Error in `assess_model_specification()`:
! There is a mismatch in the names of your constructs.
Please confirm that:
(1) the construct names in the measurement model are correcly spelled and specified;
(2) the construct names in your structural model are correctly spelled and specified;
(3) all the construct names in your structural model are specified in the measurement model.
Please note that plot(measurement_model) or plot(structural_model) help in visualizing the problem.
Model cannot be estimated.
The plot() function can also help to identify bugs. Applied to the un-estimated structural model, measurement model, or the estimated PLS path model, we find that COMP is spelled differently in the models. For more info on bug checking and resolving problems, please check demo(“seminr-debugging-problem-solving”).
Please note that we use theme = seminr_theme_academic() to display constructs as circles or ovals and indicators as rectangles as well as to use a black-and-white plotting scheme.
## Plotting a model for debugging
# Plot the measurement model
plot(error_mm, theme = seminr_theme_academic())# Plot the structural model
plot(simple_sm, theme = seminr_theme_academic())3.7 Summarizing the model
Once the model has been estimated, a summarized report of the results can be generated by using the summary() function.
The summary() function applied to a SEMinR model object produces a summary.seminr_model class object. Its sub-objects (see Tab. 2) serve as basis for the assessment of the measurement and structural model.
| Sub-object | Content |
|---|---|
| meta | The estimation function and version information. |
| iterations | The number of iterations for the PLS algorithm to converge. |
| paths | The model’s path coefficients and (adjusted) R2 values. |
| total_effects | The model’s total effects. |
| total_indirect_effects | The model’s total indirect effects. |
| loadings | The outer loadings for all constructs. |
| weights | The outer weights for all constructs. |
| validity | The metrics necessary to evaluate the construct measures’ validity. |
| reliability | The metrics necessary to evaluate the construct measures’ reliability. |
| composite_scores | The estimated scores for constructs. |
| vif_antecedents | The metrics used to evaluate structural model collinearity. |
| fSquare | The f2 metric for all structural model relationships. |
| descriptives | The descriptive statistics of the indicator data. |
| it_criteria | The information theoretic model selection criteria for the estimated model. |
| missing_data | The missing data approach and information. |
For example, by calling summary_corp_rep$paths we inspect the model’s path coefficients and the (adjusted) R2 values and by calling summary_corp_rep$reliability, we inspect the construct reliability metrics.
# Summarize the model results
summary_simple_corp_rep <- summary(corp_rep_simple_model)
# Inspect the model’s path coefficients and the (adjusted) R^2 values
summary_simple_corp_rep$paths CUSA CUSL
R^2 0.295 0.562
AdjR^2 0.290 0.558
COMP 0.162 0.009
LIKE 0.424 0.342
CUSA . 0.504
# Inspect the construct reliability metrics
summary_simple_corp_rep$reliability alpha rhoA rhoC AVE
COMP 0.776 0.832 0.865 0.681
LIKE 0.831 0.836 0.899 0.747
CUSA 1.000 1.000 1.000 1.000
CUSL 0.831 0.839 0.899 0.748
Alpha, rhoA, and rhoC should exceed 0.7 while AVE should exceed 0.5
3.8 Bootstrapping the model
In PLS-SEM, we need to perform bootstrapping to estimate standard errors and compute confidence intervals.
The rsulting object, i.e. sum_boot_corp_rep, contains the following sub-objects (Tab. 3):
| Sub-object | Content |
|---|---|
| nboot | The number of bootstrap subsamples generated during bootstrapping. |
| bootstrapped_paths | The bootstrap estimated standard error, t statistic, and confidence intervals for the path coefficients. |
| bootstrapped_weights | The bootstrap estimated standard error, t statistic, and confidence intervals for the indicator weights. |
| bootstrapped_loadings | The bootstrap estimated standard error, t statistic, and confidence intervals for the indicator loadings. |
| bootstrapped_HTMT | The bootstrap estimated standard error, t statistic, and confidence intervals for the HTMT values. |
| bootstrapped_total_paths | The bootstrap estimated standard error, t statistic, and confidence intervals for the model’s total effects. |
| bootstrapped_total_indirect_paths | The bootstrap estimated standard error, t statistic, and confidence intervals for the model’s total indirect effects. |
We run the bootstrapping with the bootstrap_model() function with 1,000 subsamples (nboot = 1000) and set a seed (seed = 123) to obtain reproducible results.
Next, we summarize the bootstrap model with sum_boot_corp_rep <- summary(boot_corp_rep) and obtain results on model estimates such as the path coefficients with sum_boot_corp_rep$bootstrapped_paths.
# Bootstrap the model
boot_simple_corp_rep <- bootstrap_model(
seminr_model = corp_rep_simple_model,
nboot = 1000,
cores = NULL,
seed = 123)Bootstrapping model using seminr...
SEMinR Model successfully bootstrapped
# Store the summary of the bootstrapped model
sum_boot_simple_corp_rep <- summary(boot_simple_corp_rep)
# Inspect the bootstrapped structural paths
sum_boot_simple_corp_rep$bootstrapped_paths Original Est. Bootstrap Mean Bootstrap SD T Stat. 2.5% CI
COMP -> CUSA 0.162 0.166 0.068 2.374 0.038
COMP -> CUSL 0.009 0.011 0.056 0.165 -0.098
LIKE -> CUSA 0.424 0.422 0.062 6.858 0.299
LIKE -> CUSL 0.342 0.340 0.056 6.059 0.227
CUSA -> CUSL 0.504 0.504 0.042 11.978 0.419
97.5% CI Bootstrap P Val
COMP -> CUSA 0.298 0.014
COMP -> CUSL 0.126 0.826
LIKE -> CUSA 0.542 0.000
LIKE -> CUSL 0.450 0.000
CUSA -> CUSL 0.585 0.000
# Inspect the bootstrapped indicator loadings
sum_boot_simple_corp_rep$bootstrapped_loadings Original Est. Bootstrap Mean Bootstrap SD T Stat. 2.5% CI
comp_1 -> COMP 0.858 0.858 0.021 41.366 0.813
comp_2 -> COMP 0.798 0.797 0.029 27.709 0.730
comp_3 -> COMP 0.818 0.814 0.031 26.246 0.746
like_1 -> LIKE 0.879 0.880 0.017 51.088 0.843
like_2 -> LIKE 0.870 0.869 0.018 47.428 0.830
like_3 -> LIKE 0.843 0.842 0.020 41.417 0.799
cusa -> CUSA 1.000 1.000 0.000 . 1.000
cusl_1 -> CUSL 0.833 0.832 0.024 35.331 0.780
cusl_2 -> CUSL 0.917 0.917 0.010 88.874 0.894
cusl_3 -> CUSL 0.843 0.842 0.023 37.134 0.793
97.5% CI Bootstrap P Val
comp_1 -> COMP 0.895 0.000
comp_2 -> COMP 0.843 0.000
comp_3 -> COMP 0.866 0.000
like_1 -> LIKE 0.910 0.000
like_2 -> LIKE 0.900 0.000
like_3 -> LIKE 0.879 0.000
cusa -> CUSA 1.000 0.000
cusl_1 -> CUSL 0.874 0.000
cusl_2 -> CUSL 0.935 0.000
cusl_3 -> CUSL 0.881 0.000
3.9 Plotting, printing, and exporting results to articles
We recommend exporting tables and matrices to .csv files, which can be imported into documents or presentations, and that figures are exported to .pdf or .png files to ensure the best print quality.
For exporting a table or matrix to .csv, we recommend using write.csv. For example, to report the bootstrapped paths from the simple model, we use the write.csv() function with argument x = sum_boot_simple_corp_rep$bootstrapped_loadings and file = "boot_loadings.csv".
# Write the bootstrapped paths object to csv file
write.csv(x = sum_boot_simple_corp_rep$bootstrapped_loadings,
file = "boot_loadings.csv")Figures can be first generated in RStudio to be exported in a separate step. To demonstrate this, we use a sub-object of summary_simple_corp_rep and plot the constructs’ internal consistency reliability estimates (i.e., Cronbach’s alpha, rhoA, and rhoC) using the plot() function.
Figure 2 shows the output (the plot shown in R Studio’s “Plots” Window) and highlight the use of “Export” to save the plot as PDF.
# Plot the internal consistency consistency reliability estimates
plot(summary_simple_corp_rep$reliability)4 Chapter 4: Evaluation of reflective measurement models
4.1 Model set-up
We use the corporate reputation data set and the corporate reputation model specified in Chapter 3.
Below, we conduct the following steps:
Load the packages
seminrandseminrExtrasLoad the
crop_rep_dataCreate the measurement model
corp_rep_mmCreate the structural model
corp_rep_smEstimate the model and store the estimated model in
corp_rep_pls_modelSummarize the estimated model in
summary_corp_rep
See Section 3 for detailed explanations of the code.
# This analysis requires the psych and paran packages (refer to Section 2.6 in the book)
# Load the SEMinR and seminrExtras libraries
library(seminr)
library(seminrExtras)
# Load the data ----
corp_rep_data <- corp_rep_data
# Create measurement model ----
corp_rep_mm <- constructs(
composite("COMP", multi_items("comp_", 1:3)),
composite("LIKE", multi_items("like_", 1:3)),
composite("CUSA", single_item("cusa")),
composite("CUSL", multi_items("cusl_", 1:3)))
# Create structural model ----
corp_rep_sm <- relationships(
paths(from = c("COMP", "LIKE"), to = c("CUSA", "CUSL")),
paths(from = c("CUSA"), to = c("CUSL")))
# Estimating the model
corp_rep_pls_model <- estimate_pls(
data = corp_rep_data,
measurement_model = corp_rep_mm,
structural_model = corp_rep_sm,
missing = mean_replacement,
missing_value = "-99")Generating the seminr model
All 344 observations are valid.
# Summarize the model results
summary_corp_rep <- summary(corp_rep_pls_model)Before evaluating the measurement and the structural model, we check whether the PLS algorithm has converged.
The number resulting from summary_corp_rep$iterations indicates the number of iterations the PLS algorithm required to converge. The value should be lower than the value in the maxIt argument set in estimate_pls(). The default value for maxIt is 300. In out example, the algorithm converged after 4 iterations.
# Iterations to converge
summary_corp_rep$iterations[1] 4
4.2 Unidimensionality
We initially check unidimensionality for the reflective constructs COMP, LIKE, and CUSL.
To do so, we perform the following steps:
Set up a list of the reflective constructs and their indicators in
con.list.Collect the data from the
seminr_modelobjectcorp_rep_pls_modelindim_data.Set up helper functions to estimate Revelle’s beta (
est_dim) and to test for unidimensionality (test_unidim).Perform principal components analysis (PCA) to obtain eigenvalues for the first three principal components (
PCA_results).Perform parallel analysis using the
paranpackage to obtain adjusted eigenvalues for the first three principal components (para_results).
# Evaluate the undimensionality of reflective constructs
## Set up the list of reflective constructs
con.list <- list(COMP = multi_items("comp_", 1:3),
LIKE = multi_items("like_", 1:3),
CUSL = multi_items("cusl_", 1:3))
## Collect the cleaned data from the seminr_model object
## (The missing values have already been treated/imputed)
dim_data <- corp_rep_pls_model$data
## Set up helper functions (using psych package)
est_dim <- function(construct, data) {
ret <- psych::iclust(data[,construct],
nclusters = 1)$beta
}
## Test for unidimensionality
test_unidim <- function(con.list, sum.model, dim_data) {
dims_results <- lapply(con.list, function(x) est_dim(x, dim_data))
dims_results <- unlist(dims_results)
names(dims_results) <- names(con.list)
alphas <- sum.model$reliability[names(con.list),"alpha"]
dims_results <- data.frame(
"Cronbach Alpha" = alphas,
"Revelle Beta" = dims_results)
return(dims_results)
}
## Principal Components Analysis Test
PCA_results <- matrix(c(base::eigen(cor(dim_data[,con.list[["COMP"]]]))$values,
base::eigen(cor(dim_data[,con.list[["CUSL"]]]))$values,
base::eigen(cor(dim_data[,con.list[["LIKE"]]]))$values),
nrow = 3, byrow = TRUE,
dimnames = list(c("COMP", "CUSL", "LIKE"),
c("PC1 EV", "PC2 EV", "PC3 EV")))
# Parallel analysis (using paran package)
paran_comp <- paran::paran(dim_data[,con.list[["COMP"]]],
iterations=1000,
centile=95)
Using eigendecomposition of correlation matrix.
Computing: 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%
Results of Horn's Parallel Analysis for component retention
1000 iterations, using the 95 centile estimate
--------------------------------------------------
Component Adjusted Unadjusted Estimated
Eigenvalue Eigenvalue Bias
--------------------------------------------------
1 1.920768 2.076027 0.155258
--------------------------------------------------
Adjusted eigenvalues > 1 indicate dimensions to retain.
(1 components retained)
paran_cusl <- paran::paran(dim_data[,con.list[["CUSL"]]],
iterations=1000,
centile=95)
Using eigendecomposition of correlation matrix.
Computing: 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%
Results of Horn's Parallel Analysis for component retention
1000 iterations, using the 95 centile estimate
--------------------------------------------------
Component Adjusted Unadjusted Estimated
Eigenvalue Eigenvalue Bias
--------------------------------------------------
1 2.099378 2.245435 0.146057
--------------------------------------------------
Adjusted eigenvalues > 1 indicate dimensions to retain.
(1 components retained)
paran_like <- paran::paran(dim_data[,con.list[["LIKE"]]],
iterations=1000,
centile=95)
Using eigendecomposition of correlation matrix.
Computing: 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%
Results of Horn's Parallel Analysis for component retention
1000 iterations, using the 95 centile estimate
--------------------------------------------------
Component Adjusted Unadjusted Estimated
Eigenvalue Eigenvalue Bias
--------------------------------------------------
1 2.091594 2.242329 0.150735
--------------------------------------------------
Adjusted eigenvalues > 1 indicate dimensions to retain.
(1 components retained)
para_results <- matrix(c(paran_comp$AdjEv,paran_cusl$AdjEv,paran_like$AdjEv),
nrow = 3, byrow = TRUE,
dimnames = list(c("COMP", "CUSL", "LIKE"),
c("PC1 EV", "PC2 EV", "PC3 EV")))
## Display the results of the unidimensionality tests
round(test_unidim(con.list, summary_corp_rep, dim_data),2) Cronbach.Alpha Revelle.Beta
COMP 0.78 0.70
LIKE 0.83 0.81
CUSL 0.83 0.78
round(PCA_results,2) PC1 EV PC2 EV PC3 EV
COMP 2.08 0.57 0.35
CUSL 2.25 0.49 0.26
LIKE 2.24 0.41 0.35
round(para_results,2) PC1 EV PC2 EV PC3 EV
COMP 1.92 0.54 0.38
CUSL 2.10 0.46 0.29
LIKE 2.09 0.37 0.38
We assess unidimensionality in three steps by checking the following criteria:
- Comparing Revelle’s beta with the Cronbach’s alpha values shows that the beta values for COMP, CUSL, and LIKE are 0.08 (i.e., 0.78-0.70), 0.05 (i.e., 0.83-0.78), and 0.02 (i.e., 0.83-0.81) units lower than the corresponding alpha values. ➝ Supporting unidimensionality
- The eigenvalues generated from the PCA indicate that all reflective constructs have first eigenvalues larger than one (COMP: 2.08; CUSL: 2.25; and LIKE: 2.24), while all second eigenvalues are lower than one (COMP: 0.57; CUSL: 0.49; and LIKE: 0.41). ➝ Supporting unidimensionality
- The parallel analysis confirms the PCA results since the first set of simulated eigenvalues (COMP: 1.92; CUSL: 2.09; and LIKE: 2.09) is smaller than the corresponding empirical eigenvalues. ➝ Supporting unidimensionality
Since all of these criteria are met, we conclude that the reflective constructs COMP, CUSL, and LIKE are unidimensional and continue with the evaluation of the measurement model.
4.3 Indicator reliability
For the reflective measurement model, we need to estimate the relationships between the reflectively measured constructs and their indicators (i.e., loadings). Indicator reliability can be calculated by squaring the loadings.
Low indicator reliability may result in biased construct results. Therefore, we evaluate indicator loadings as follows:
Indicator loadings above 0.708 are recommended, since they correspond to an explained variance (indicator reliabilty) of at least 50%.
Indicators with loadings between 0.40 and 0.70 should be considered for removal.
Indicators with very low loadings (below 0.40) should be removed.
We can get the loadings by inspecting the summary_corp_rep object’s loadings element (summary_corp_rep$loadings) and we can get the indicator reliabilities by squaring the loadings.
# Inspect the indicator loadings
summary_corp_rep$loadings COMP LIKE CUSA CUSL
comp_1 0.858 0.000 0.000 0.000
comp_2 0.798 0.000 0.000 0.000
comp_3 0.818 0.000 0.000 0.000
like_1 0.000 0.879 0.000 0.000
like_2 0.000 0.870 0.000 0.000
like_3 0.000 0.843 0.000 0.000
cusa 0.000 0.000 1.000 0.000
cusl_1 0.000 0.000 0.000 0.833
cusl_2 0.000 0.000 0.000 0.917
cusl_3 0.000 0.000 0.000 0.843
# Inspect the indicator reliability
summary_corp_rep$loadings^2 COMP LIKE CUSA CUSL
comp_1 0.736 0.000 0.000 0.000
comp_2 0.638 0.000 0.000 0.000
comp_3 0.669 0.000 0.000 0.000
like_1 0.000 0.773 0.000 0.000
like_2 0.000 0.757 0.000 0.000
like_3 0.000 0.711 0.000 0.000
cusa 0.000 0.000 1.000 0.000
cusl_1 0.000 0.000 0.000 0.694
cusl_2 0.000 0.000 0.000 0.841
cusl_3 0.000 0.000 0.000 0.710
All indicator loadings of the reflectively measured constructs COMP, CUSL, and LIKE are well above the threshold value of 0.708 and all indicator reliabilities are well above 0.50. Thus we conclude that indicator reliability is established for all reflective constructs in the corporate reputation model.
4.4 Internal consistency reliability
We evaluate internal consistency reliability using three different metrics: Cronbach’s alpha, composite reliability (rhoC), and the exact (or consistent) reliability coefficient (rhoA).
Cronbach’s alpha which corresponds to a lower bound of internal consistency reliability (Trizano-Hermosilla & Alvarado, 2016)
Composite reliability \(\rho\)c (Jöreskog, 1971) is the upper bound for internal consistency reliability
The exact (or consistent) reliability coefficient \(\rho\)A usually lies between Cronbach’s alpha and \(\rho\)c, and may serve as a good representation of a construct’s internal consistency reliability (Dijkstra, 2014; Dijkstra & Henseler, 2015).
An item is acceptable for inclusion in the model if its internal consistency reliability takes specific values:
Recommended value of 0.80 to 0.90.
Minimum value of 0.70 (or 0.60 in exploratory research).
Maximum value of 0.95 to avoid indicator redundancy, which would compromise content validity (Diamantopoulos et al., 2012).
The reliability indicators can be found in summary_corp_rep$reliability and plotted with plot(summary_corp_rep$reliability).
# Inspect the composite reliability
summary_corp_rep$reliability alpha rhoA rhoC AVE
COMP 0.776 0.832 0.865 0.681
LIKE 0.831 0.836 0.899 0.747
CUSA 1.000 1.000 1.000 1.000
CUSL 0.831 0.839 0.899 0.748
Alpha, rhoA, and rhoC should exceed 0.7 while AVE should exceed 0.5
# Plot the reliabilities of constructs
plot(summary_corp_rep$reliability)All three internal consistency reliability metrics (i.e., Cronbach’s alpha, rhoC, and rhoA) for the reflective constructs COMP, LIKE, and CUSL exceed the recommended threshold of 0.80 ans saty below 0.95. Thus, we conclude that internal consistency reliability is established for all reflective constructs in the corporate reputation model.
4.5 Convergent validity
We asses convergent validity using the average variance extracted (AVE) metric. The AVE is the mean of a construct indicator’s squared loadings. An acceptable AVE value is 0.50 or higher (Hair et al., 2026).
AVE values can also be accessed via summary_corp_rep$reliability.
summary_corp_rep$reliability alpha rhoA rhoC AVE
COMP 0.776 0.832 0.865 0.681
LIKE 0.831 0.836 0.899 0.747
CUSA 1.000 1.000 1.000 1.000
CUSL 0.831 0.839 0.899 0.748
Alpha, rhoA, and rhoC should exceed 0.7 while AVE should exceed 0.5
Since all AVE values for the reflective constructs COMP, LIKE, and CUSL exceed the recommended threshold of 0.50, we conclude that convergent validity is established.
4.6 Discriminant validty
We recommend the heterotrait-monotrait ratio (HTMT) of the correlations to assess discriminant validity (Henseler et al., 2015).
Discriminant validity problems are present when HTMT values
- exceed 0.90 for constructs that are conceptually very similar.
- exceed 0.85 for constructs that are conceptually more distinct.
We can get the HTMT matrix by calling summary_corp_rep$validity$htmt.
summary_corp_rep$validity$htmt COMP LIKE CUSA CUSL
COMP . . . .
LIKE 0.780 . . .
CUSA 0.465 0.577 . .
CUSL 0.532 0.737 0.755 .
All HTMT values are below the threshold of 0.85, indicating that discriminant validity is established for all reflective constructs in the corporate reputation model.
Bootstrap confidence intervals now help test if the HTMT is significantly different from 1.00 (Henseler et al., 2015) or a lower threshold value such as 0.90 or 0.85 (Franke & Sarstedt, 2019).
We obtain the HTMT 90% bootstrap CI by, first, bootstrapping the PLS model (corp_rep_pls_model) using bootstrap_model() into the boot_corp_repobject and, second, by calling sum_boot_corp_rep <- summary(boot_corp_rep, alpha = 0.10) and inspecting the object sum_boot_corp_rep$bootstrapped_HTMT.
Please note that we set alpha = 0.10 to obtain the 90% confidence intervals which is equivalent to running a one-tailed test at 5%, needed for discriminant validity testing.
# Bootstrap the model
boot_corp_rep <- bootstrap_model(seminr_model = corp_rep_pls_model,
nboot = 1000)Bootstrapping model using seminr...
SEMinR Model successfully bootstrapped
# Store the summary of the bootstrapped model
sum_boot_corp_rep <- summary(boot_corp_rep, alpha = 0.10)After estimation, we inspect the bootstrapped HTMT results by calling sum_boot_corp_rep$bootstrapped_HTMT.
# Extract the bootstrapped HTMT
sum_boot_corp_rep$bootstrapped_HTMT Original Est. Bootstrap Mean Bootstrap SD T Stat. 5% CI 95% CI
COMP -> LIKE 0.780 0.778 0.042 5.299 0.708 0.842
COMP -> CUSA 0.465 0.462 0.055 9.660 0.369 0.552
COMP -> CUSL 0.532 0.534 0.056 8.377 0.445 0.628
LIKE -> CUSA 0.577 0.574 0.042 10.057 0.504 0.642
LIKE -> CUSL 0.737 0.736 0.041 6.439 0.669 0.804
CUSA -> CUSL 0.755 0.755 0.034 7.152 0.697 0.808
Bootstrap P Val
COMP -> LIKE 0.000
COMP -> CUSA 0.000
COMP -> CUSL 0.000
LIKE -> CUSA 0.000
LIKE -> CUSL 0.000
CUSA -> CUSL 0.000
The output displays the following elements:
The original HTMT estimates (column:
Original Est.)The bootstrapped mean ratio estimates (column:
Bootstrap Mean)The bootstrap standard deviation (column:
Bootstrap SD)The bootstrap t-values (column:
T Stat.)The 90% confidence interval (columns:
5% CIand95% CI)
Please note that the results might differ slightly from the results you obtain our your own system.
Since the confidence intervals’ upper bounds are always lower than the threshold value of 0.90 (and even 0.85), we conclude that discriminant validity is established for all reflective constructs in the corporate reputation model.
4.7 Congruence coefficient
As an additional test for discriminant validity, we assess the construct congruence using the congruence_test() function.
# Calculate the bootstrapped congruence coefficient rc
congruence_test(corp_rep_pls_model, alpha = 0.10)$results Original Est. Diff Bootstrap SD T Stat. 5% CI 95% CI
COMP -> LIKE 0.961 0.039 0.013 3.063 0.937 0.978
COMP -> CUSA 0.841 0.159 0.037 4.302 0.776 0.895
COMP -> CUSL 0.893 0.107 0.025 4.309 0.847 0.928
LIKE -> CUSA 0.875 0.125 0.032 3.946 0.819 0.921
LIKE -> CUSL 0.940 0.060 0.016 3.760 0.911 0.962
CUSA -> CUSL 0.961 0.039 0.010 3.706 0.941 0.975
We find that all constructs have congruence coefficient that are significantly smaller than 1.0 at the 5% confidence level (column 97.5% CI). These results provide further show that discriminant validity is strongly supported.
5 Chapter 5: Evaluation of formative measurement models
Relevant criteria for evaluating formative measurement models include the assessment of:
- Convergent validity.
- Indicator collinearity.
- Statistical significance and relevance of the indicator weights.
5.1 Model set-up and estimation
Here, we work with an extended corporate reputation model as displayed below in Figure 3.
Tab. 4 shows the model’s measurement details, i.e. the constructs, variable names and items for the formative constructs:
- QUAL: The quality of a company’s products and services as well as its quality of customer orientation.
- PERF: The company’s economic and managerial performance.
- CSOR: The company’s corporate social responsibility.
- ATTR: The company’s attractivenessa s an employer.
constructs_ext <- c(rep("Quality (QUAL)", 8),
rep("Performance (PERF)", 5),
rep("Corporate Social Responsibility (CSOR)", 5),
rep("Attractiveness (ATTR)",3),
rep("Single-item measure for the redundancy analysis", 4))
ext_ModelMM <- cbind(constructs_ext,
c("qual_1","qual_2","qual_3","qual_4","qual_5","qual_6","qual_7","qual_8","perf_1","perf_2","perf_3","perf_4","perf_5","csor_1","csor_2","csor_3","csor_4","csor_5","attr_1","attr_2","attr_3","qual_global","perf_global","csor_global","attr_global"),
c("The products/services offered by [the company] are of high quality.",
"[The company] is an innovator, rather than an imitator with respect to [industry].",
"[The company]’s products/services offer good value for money.",
"The services [the company] offered are good.",
"Customer concerns are held in high regard at [the company].",
"[The company] is a reliable partner for customers.",
"[The company] is a trustworthy company.",
"I have a lot of respect for [the company].",
"[The company] is a very well-managed company.",
"[The company] is an economically stable company.",
"The business risk for [the company] is modest compared to its competitors.",
"[The company] has growth potential.",
"[The company] has a clear vision about the future of the company.",
"[The company] behaves in a socially conscious way.",
"[The company] is forthright in giving information to the public.",
"[The company] has a fair attitude toward competitors.",
"[The company] is concerned about the preservation of the environment.",
"[The company] is not only concerned about profits.",
"[The company] is successful in attracting high-quality employees.",
"I could see myself working at [the company].",
"I like the physical appearance of [the company] (company, buildings, shops, etc.).",
"Please assess the overall quality of [the company’s] activities.",
"Please assess [the company’s] overall performance.",
"Please assess the extent to which [the company] acts in socially conscious ways.",
"Please assess [the company’s] overall attractiveness."
))
colnames(ext_ModelMM) <- c("construct", "variable name", "item")
knitr::kable(ext_ModelMM,
caption = "**Tab. 4** Measurement details for the extended corporate reputation model.")| construct | variable name | item |
|---|---|---|
| Quality (QUAL) | qual_1 | The products/services offered by [the company] are of high quality. |
| Quality (QUAL) | qual_2 | [The company] is an innovator, rather than an imitator with respect to [industry]. |
| Quality (QUAL) | qual_3 | [The company]’s products/services offer good value for money. |
| Quality (QUAL) | qual_4 | The services [the company] offered are good. |
| Quality (QUAL) | qual_5 | Customer concerns are held in high regard at [the company]. |
| Quality (QUAL) | qual_6 | [The company] is a reliable partner for customers. |
| Quality (QUAL) | qual_7 | [The company] is a trustworthy company. |
| Quality (QUAL) | qual_8 | I have a lot of respect for [the company]. |
| Performance (PERF) | perf_1 | [The company] is a very well-managed company. |
| Performance (PERF) | perf_2 | [The company] is an economically stable company. |
| Performance (PERF) | perf_3 | The business risk for [the company] is modest compared to its competitors. |
| Performance (PERF) | perf_4 | [The company] has growth potential. |
| Performance (PERF) | perf_5 | [The company] has a clear vision about the future of the company. |
| Corporate Social Responsibility (CSOR) | csor_1 | [The company] behaves in a socially conscious way. |
| Corporate Social Responsibility (CSOR) | csor_2 | [The company] is forthright in giving information to the public. |
| Corporate Social Responsibility (CSOR) | csor_3 | [The company] has a fair attitude toward competitors. |
| Corporate Social Responsibility (CSOR) | csor_4 | [The company] is concerned about the preservation of the environment. |
| Corporate Social Responsibility (CSOR) | csor_5 | [The company] is not only concerned about profits. |
| Attractiveness (ATTR) | attr_1 | [The company] is successful in attracting high-quality employees. |
| Attractiveness (ATTR) | attr_2 | I could see myself working at [the company]. |
| Attractiveness (ATTR) | attr_3 | I like the physical appearance of [the company] (company, buildings, shops, etc.). |
| Single-item measure for the redundancy analysis | qual_global | Please assess the overall quality of [the company’s] activities. |
| Single-item measure for the redundancy analysis | perf_global | Please assess [the company’s] overall performance. |
| Single-item measure for the redundancy analysis | csor_global | Please assess the extent to which [the company] acts in socially conscious ways. |
| Single-item measure for the redundancy analysis | attr_global | Please assess [the company’s] overall attractiveness. |
According to the extended model, we update the measurement and structural model specifications. Note that the four drivers QUAL, PERF, CSOR, and ATTR are formative constructs, estimated with mode_B, while COMP and LIKE are reflective, estimated with mode_A (default setting in the composite() function).
Once the model is set up, we estimate the model with estimate_pls() and store it in corp_rep_pls_model_ext to summarize it with summary(corp_rep_pls_model_ext).
# Create measurement model ----
corp_rep_mm_ext <- constructs(
composite("QUAL", multi_items("qual_", 1:8), weights = mode_B),
composite("PERF", multi_items("perf_", 1:5), weights = mode_B),
composite("CSOR", multi_items("csor_", 1:5), weights = mode_B),
composite("ATTR", multi_items("attr_", 1:3), weights = mode_B),
composite("COMP", multi_items("comp_", 1:3)),
composite("LIKE", multi_items("like_", 1:3)),
composite("CUSA", single_item("cusa")),
composite("CUSL", multi_items("cusl_", 1:3))
)
# Create structural model ----
corp_rep_sm_ext <- relationships(
paths(from = c("QUAL", "PERF", "CSOR", "ATTR"), to = c("COMP", "LIKE")),
paths(from = c("COMP", "LIKE"), to = c("CUSA", "CUSL")),
paths(from = c("CUSA"), to = c("CUSL"))
)
# Estimate the model ----
corp_rep_pls_model_ext <- estimate_pls(
data = corp_rep_data,
measurement_model = corp_rep_mm_ext,
structural_model = corp_rep_sm_ext,
missing = mean_replacement,
missing_value = "-99")Generating the seminr model
All 344 observations are valid.
# Summarize the model results
summary_corp_rep_ext <- summary(corp_rep_pls_model_ext)We also check the number of iteration until convergence (which should be below the default maximum number of 300 iterations).
# Iterations to converge
summary_corp_rep_ext$iterations[1] 8
Next, we bootstrap the model (bootstrap_model()), summarize the result with a 90% CI by calling summary(boot_corp_rep_ext, alpha = 0.10) and store the result in sum_boot_corp_rep_ext.
# Bootstrap the model
boot_corp_rep_ext <- bootstrap_model(seminr_model = corp_rep_pls_model_ext,
nboot = 1000,
seed = 123)Bootstrapping model using seminr...
SEMinR Model successfully bootstrapped
# Store the summary of the bootstrapped model
sum_boot_corp_rep_ext <- summary(boot_corp_rep_ext, alpha = 0.10)5.2 Reflective measurement model evaluation
Wwe must ensure that the extended model remains valid and reliable before continuing to evaluate the four new exogenous formative constructs. To do so, we follow the reflective measurement model assessment procedure outlined in Chapter 4 (see Section 4).
The code below conducts the measurement model evaluation for the extended corporate reputation model. (Please note that you only have to reload seminr and seminrExtras if you detached these packages or started a new R session.)
# Load the SEMinR and seminrExtras libraries
library(seminr)
library(seminrExtras)
# Load the corporate repuation data
corp_rep_data <- corp_rep_data
# Create measurement model ----
corp_rep_mm_ext <- constructs(
composite("QUAL", multi_items("qual_", 1:8), weights = mode_B),
composite("PERF", multi_items("perf_", 1:5), weights = mode_B),
composite("CSOR", multi_items("csor_", 1:5), weights = mode_B),
composite("ATTR", multi_items("attr_", 1:3), weights = mode_B),
composite("COMP", multi_items("comp_", 1:3)),
composite("LIKE", multi_items("like_", 1:3)),
composite("CUSA", single_item("cusa")),
composite("CUSL", multi_items("cusl_", 1:3))
)
# Create structural model ----
corp_rep_sm_ext <- relationships(
paths(from = c("QUAL", "PERF", "CSOR", "ATTR"), to = c("COMP", "LIKE")),
paths(from = c("COMP", "LIKE"), to = c("CUSA", "CUSL")),
paths(from = c("CUSA"), to = c("CUSL"))
)
# Estimate the model ----
corp_rep_pls_model_ext <- estimate_pls(
data = corp_rep_data,
measurement_model = corp_rep_mm_ext,
structural_model = corp_rep_sm_ext,
missing = mean_replacement,
missing_value = "-99")Generating the seminr model
All 344 observations are valid.
# Summarize the model results
summary_corp_rep_ext <- summary(corp_rep_pls_model_ext)
# Iterations to converge
summary_corp_rep_ext$iterations[1] 8
# Bootstrap the model
boot_corp_rep_ext <- bootstrap_model(seminr_model = corp_rep_pls_model_ext,
nboot = 1000,
seed = 123)Bootstrapping model using seminr...
SEMinR Model successfully bootstrapped
# Store the summary of the bootstrapped model
sum_boot_corp_rep_ext <- summary(boot_corp_rep_ext, alpha = 0.10)In the following, we assess indicator loadings (summary_corp_rep_ext$loadings), indicator reliability (summary_corp_rep_ext$loadings^2), internal consistency reliability (summary_corp_rep_ext$reliability), and discriminant validity (summary_corp_rep_ext$validity$htmt and sum_boot_corp_rep_ext$bootstrapped_HTMT) for the reflective constructs COMP, LIKE, CUSA, and CUSL in the extended corporate reputation model.
Please note that the outputs contain the estimates for both reflective and formative constructs although only the reflectively measured constructs need to be evaluated now.
After the addition of the new measurement models and their structural paths, the reflectively measured constructs continue to meet all criteria.
Please see the book’s Appendix B for details on the interpretation of the estimates.
# Inspect the indicator loadings
summary_corp_rep_ext$loadings QUAL PERF CSOR ATTR COMP LIKE CUSA CUSL
qual_1 0.741 0.000 0.000 0.000 0.000 0.000 0.000 0.000
qual_2 0.570 0.000 0.000 0.000 0.000 0.000 0.000 0.000
qual_3 0.749 0.000 0.000 0.000 0.000 0.000 0.000 0.000
qual_4 0.664 0.000 0.000 0.000 0.000 0.000 0.000 0.000
qual_5 0.787 0.000 0.000 0.000 0.000 0.000 0.000 0.000
qual_6 0.856 0.000 0.000 0.000 0.000 0.000 0.000 0.000
qual_7 0.722 0.000 0.000 0.000 0.000 0.000 0.000 0.000
qual_8 0.627 0.000 0.000 0.000 0.000 0.000 0.000 0.000
perf_1 0.000 0.846 0.000 0.000 0.000 0.000 0.000 0.000
perf_2 0.000 0.690 0.000 0.000 0.000 0.000 0.000 0.000
perf_3 0.000 0.573 0.000 0.000 0.000 0.000 0.000 0.000
perf_4 0.000 0.717 0.000 0.000 0.000 0.000 0.000 0.000
perf_5 0.000 0.638 0.000 0.000 0.000 0.000 0.000 0.000
csor_1 0.000 0.000 0.771 0.000 0.000 0.000 0.000 0.000
csor_2 0.000 0.000 0.571 0.000 0.000 0.000 0.000 0.000
csor_3 0.000 0.000 0.838 0.000 0.000 0.000 0.000 0.000
csor_4 0.000 0.000 0.617 0.000 0.000 0.000 0.000 0.000
csor_5 0.000 0.000 0.848 0.000 0.000 0.000 0.000 0.000
attr_1 0.000 0.000 0.000 0.754 0.000 0.000 0.000 0.000
attr_2 0.000 0.000 0.000 0.506 0.000 0.000 0.000 0.000
attr_3 0.000 0.000 0.000 0.891 0.000 0.000 0.000 0.000
comp_1 0.000 0.000 0.000 0.000 0.824 0.000 0.000 0.000
comp_2 0.000 0.000 0.000 0.000 0.821 0.000 0.000 0.000
comp_3 0.000 0.000 0.000 0.000 0.844 0.000 0.000 0.000
like_1 0.000 0.000 0.000 0.000 0.000 0.880 0.000 0.000
like_2 0.000 0.000 0.000 0.000 0.000 0.869 0.000 0.000
like_3 0.000 0.000 0.000 0.000 0.000 0.844 0.000 0.000
cusa 0.000 0.000 0.000 0.000 0.000 0.000 1.000 0.000
cusl_1 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.833
cusl_2 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.917
cusl_3 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.843
# Inspect the indicator reliability
summary_corp_rep_ext$loadings^2 QUAL PERF CSOR ATTR COMP LIKE CUSA CUSL
qual_1 0.548 0.000 0.000 0.000 0.000 0.000 0.000 0.000
qual_2 0.325 0.000 0.000 0.000 0.000 0.000 0.000 0.000
qual_3 0.561 0.000 0.000 0.000 0.000 0.000 0.000 0.000
qual_4 0.441 0.000 0.000 0.000 0.000 0.000 0.000 0.000
qual_5 0.619 0.000 0.000 0.000 0.000 0.000 0.000 0.000
qual_6 0.732 0.000 0.000 0.000 0.000 0.000 0.000 0.000
qual_7 0.521 0.000 0.000 0.000 0.000 0.000 0.000 0.000
qual_8 0.393 0.000 0.000 0.000 0.000 0.000 0.000 0.000
perf_1 0.000 0.716 0.000 0.000 0.000 0.000 0.000 0.000
perf_2 0.000 0.476 0.000 0.000 0.000 0.000 0.000 0.000
perf_3 0.000 0.328 0.000 0.000 0.000 0.000 0.000 0.000
perf_4 0.000 0.514 0.000 0.000 0.000 0.000 0.000 0.000
perf_5 0.000 0.407 0.000 0.000 0.000 0.000 0.000 0.000
csor_1 0.000 0.000 0.595 0.000 0.000 0.000 0.000 0.000
csor_2 0.000 0.000 0.325 0.000 0.000 0.000 0.000 0.000
csor_3 0.000 0.000 0.703 0.000 0.000 0.000 0.000 0.000
csor_4 0.000 0.000 0.380 0.000 0.000 0.000 0.000 0.000
csor_5 0.000 0.000 0.719 0.000 0.000 0.000 0.000 0.000
attr_1 0.000 0.000 0.000 0.569 0.000 0.000 0.000 0.000
attr_2 0.000 0.000 0.000 0.256 0.000 0.000 0.000 0.000
attr_3 0.000 0.000 0.000 0.794 0.000 0.000 0.000 0.000
comp_1 0.000 0.000 0.000 0.000 0.679 0.000 0.000 0.000
comp_2 0.000 0.000 0.000 0.000 0.673 0.000 0.000 0.000
comp_3 0.000 0.000 0.000 0.000 0.712 0.000 0.000 0.000
like_1 0.000 0.000 0.000 0.000 0.000 0.774 0.000 0.000
like_2 0.000 0.000 0.000 0.000 0.000 0.755 0.000 0.000
like_3 0.000 0.000 0.000 0.000 0.000 0.713 0.000 0.000
cusa 0.000 0.000 0.000 0.000 0.000 0.000 1.000 0.000
cusl_1 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.694
cusl_2 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.841
cusl_3 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.710
# Inspect the internal consistency and reliability
summary_corp_rep_ext$reliability alpha rhoA rhoC AVE
QUAL 0.878 1.000 0.894 0.518
PERF 0.747 1.000 0.824 0.488
CSOR 0.816 1.000 0.854 0.545
ATTR 0.600 1.000 0.770 0.540
COMP 0.776 0.786 0.869 0.688
LIKE 0.831 0.836 0.899 0.747
CUSA 1.000 1.000 1.000 1.000
CUSL 0.831 0.839 0.899 0.748
Alpha, rhoA, and rhoC should exceed 0.7 while AVE should exceed 0.5
# HTMT criterion
summary_corp_rep_ext$validity$htmt QUAL PERF CSOR ATTR COMP LIKE CUSA CUSL
QUAL . . . . . . . .
PERF 0.918 . . . . . . .
CSOR 0.809 0.738 . . . . . .
ATTR 0.896 0.911 0.826 . . . . .
COMP 0.864 0.946 0.678 0.847 . . . .
LIKE 0.828 0.790 0.741 0.840 0.780 . . .
CUSA 0.564 0.479 0.444 0.548 0.465 0.577 . .
CUSL 0.652 0.591 0.460 0.620 0.532 0.737 0.755 .
# Extract the bootstrapped HTMT
sum_boot_corp_rep_ext$bootstrapped_HTMT Original Est. Bootstrap Mean Bootstrap SD T Stat. 5% CI 95% CI
QUAL -> PERF 0.918 0.917 0.034 2.412 0.860 0.968
QUAL -> CSOR 0.809 0.807 0.029 6.511 0.756 0.851
QUAL -> ATTR 0.896 0.893 0.052 1.979 0.805 0.976
QUAL -> COMP 0.864 0.864 0.029 4.768 0.817 0.909
QUAL -> LIKE 0.828 0.827 0.029 5.898 0.776 0.875
QUAL -> CUSA 0.564 0.563 0.045 9.727 0.487 0.631
QUAL -> CUSL 0.652 0.651 0.045 7.722 0.574 0.723
PERF -> CSOR 0.738 0.737 0.044 5.993 0.661 0.804
PERF -> ATTR 0.911 0.911 0.046 1.949 0.833 0.986
PERF -> COMP 0.946 0.948 0.038 1.424 0.881 1.003
PERF -> LIKE 0.790 0.791 0.045 4.669 0.718 0.861
PERF -> CUSA 0.479 0.478 0.061 8.600 0.380 0.575
PERF -> CUSL 0.591 0.590 0.056 7.336 0.499 0.684
CSOR -> ATTR 0.826 0.826 0.052 3.341 0.743 0.914
CSOR -> COMP 0.678 0.675 0.047 6.906 0.594 0.751
CSOR -> LIKE 0.741 0.740 0.041 6.382 0.673 0.805
CSOR -> CUSA 0.444 0.443 0.049 11.241 0.360 0.522
CSOR -> CUSL 0.460 0.457 0.052 10.452 0.369 0.544
ATTR -> COMP 0.847 0.846 0.063 2.436 0.746 0.950
ATTR -> LIKE 0.840 0.841 0.050 3.170 0.759 0.925
ATTR -> CUSA 0.548 0.548 0.060 7.529 0.446 0.642
ATTR -> CUSL 0.620 0.620 0.064 5.982 0.516 0.718
COMP -> LIKE 0.780 0.782 0.041 5.369 0.716 0.849
COMP -> CUSA 0.465 0.467 0.060 8.965 0.368 0.563
COMP -> CUSL 0.532 0.534 0.059 7.867 0.438 0.631
LIKE -> CUSA 0.577 0.577 0.044 9.647 0.502 0.647
LIKE -> CUSL 0.737 0.736 0.041 6.389 0.669 0.802
CUSA -> CUSL 0.755 0.755 0.034 7.229 0.699 0.809
Bootstrap P Val
QUAL -> PERF 0.008
QUAL -> CSOR 0.000
QUAL -> ATTR 0.034
QUAL -> COMP 0.000
QUAL -> LIKE 0.000
QUAL -> CUSA 0.000
QUAL -> CUSL 0.000
PERF -> CSOR 0.000
PERF -> ATTR 0.036
PERF -> COMP 0.134
PERF -> LIKE 0.000
PERF -> CUSA 0.000
PERF -> CUSL 0.000
CSOR -> ATTR 0.000
CSOR -> COMP 0.000
CSOR -> LIKE 0.000
CSOR -> CUSA 0.000
CSOR -> CUSL 0.000
ATTR -> COMP 0.018
ATTR -> LIKE 0.002
ATTR -> CUSA 0.000
ATTR -> CUSL 0.000
COMP -> LIKE 0.000
COMP -> CUSA 0.000
COMP -> CUSL 0.000
LIKE -> CUSA 0.000
LIKE -> CUSL 0.000
CUSA -> CUSL 0.000
5.3 Formative measurement model evaluation
5.3.1 Convergent validity assessment
To examine the formatively measured constructs’ convergent validity, we carry out a separate redundancy analysis for each construct (see Fig. 4). The survey contained global single-item measures with generic assessments of the four phenomena—attractiveness, corporate social responsibility, performance, and quality—that we can use as measures of the dependent construct in the redundancy analyses (attr_global, csor_global, perf_global, and qual_global).
To run the redundancy analysis for a formatively measured construct (e.g. attractiveness), we take the following steps:
Measurement model: Assign its multi-item, formative measures to the latent variable
ATTR_Fviacomposite("ATTR_F", multi_items("attr_", 1:3), weights = mode_B)and we assign an alternative measure (attr_global) of the same concept toATTR_Gviacomposite("ATTR_G", single_item("attr_global")).Structural model: Assign a single path from
ATTR_FtoATTR_GEstimate and summarize the model: Perform the redundancy analysis by estimating the model with
estimate_pls()and summarize it.Repeat with all formative constructs separatly.
# Redundancy analysis ----
# ATTR ----
# Create measurement model
ATTR_redundancy_mm <- constructs(
composite("ATTR_F", multi_items("attr_", 1:3), weights = mode_B),
composite("ATTR_G", single_item("attr_global"))
)
# Create structural model
ATTR_redundancy_sm <- relationships(
paths(from = c("ATTR_F"), to = c("ATTR_G"))
)
# Estimate the model
ATTR_redundancy_pls_model <- estimate_pls(
data = corp_rep_data,
measurement_model = ATTR_redundancy_mm,
structural_model = ATTR_redundancy_sm,
missing = mean_replacement,
missing_value = "-99")Generating the seminr model
All 344 observations are valid.
# Summarize the model
sum_ATTR_red_model <- summary(ATTR_redundancy_pls_model)
# CSOR ----
# Create measurement model
CSOR_redundancy_mm <- constructs(
composite("CSOR_F", multi_items("csor_", 1:5), weights = mode_B),
composite("CSOR_G", single_item("csor_global"))
)
# Create structural model
CSOR_redundancy_sm <- relationships(
paths(from = c("CSOR_F"), to = c("CSOR_G"))
)
# Estimate the model
CSOR_redundancy_pls_model <- estimate_pls(
data = corp_rep_data,
measurement_model = CSOR_redundancy_mm,
structural_model = CSOR_redundancy_sm,
missing = mean_replacement,
missing_value = "-99")Generating the seminr model
All 344 observations are valid.
# Summarize the model
sum_CSOR_red_model <- summary(CSOR_redundancy_pls_model)
# PERF ----
# Create measurement model
PERF_redundancy_mm <- constructs(
composite("PERF_F", multi_items("perf_", 1:5), weights = mode_B),
composite("PERF_G", single_item("perf_global"))
)
# Create structural model
PERF_redundancy_sm <- relationships(
paths(from = c("PERF_F"), to = c("PERF_G"))
)
# Estimate the model
PERF_redundancy_pls_model <- estimate_pls(
data = corp_rep_data,
measurement_model = PERF_redundancy_mm,
structural_model = PERF_redundancy_sm,
missing = mean_replacement,
missing_value = "-99")Generating the seminr model
All 344 observations are valid.
# Summarize the model
sum_PERF_red_model <- summary(PERF_redundancy_pls_model)
# QUAL ----
# Create measurement model
QUAL_redundancy_mm <- constructs(
composite("QUAL_F", multi_items("qual_", 1:8), weights = mode_B),
composite("QUAL_G", single_item("qual_global"))
)
# Create structural model
QUAL_redundancy_sm <- relationships(
paths(from = c("QUAL_F"), to = c("QUAL_G"))
)
# Estimate the model
QUAL_redundancy_pls_model <- estimate_pls(
data = corp_rep_data,
measurement_model = QUAL_redundancy_mm,
structural_model = QUAL_redundancy_sm,
missing = mean_replacement,
missing_value = "-99")Generating the seminr model
All 344 observations are valid.
# Summarize the model
sum_QUAL_red_model <- summary(QUAL_redundancy_pls_model)
# Check the path coefficients for convergent validity
sum_ATTR_red_model$paths ATTR_G
R^2 0.764
AdjR^2 0.763
ATTR_F 0.874
sum_CSOR_red_model$paths CSOR_G
R^2 0.735
AdjR^2 0.734
CSOR_F 0.857
sum_PERF_red_model$paths PERF_G
R^2 0.657
AdjR^2 0.656
PERF_F 0.811
sum_QUAL_red_model$paths QUAL_G
R^2 0.648
AdjR^2 0.647
QUAL_F 0.805
All path coefficients are above 0.708 , indicating that the formative constructs explain more than 50% of the variance in their respective global measures. This result provides support for the formatively measured construct’s convergent validity.
5.3.2 Collinearity assessment
To assess collinearity among the indicators of each formative construct, we inspect the variance inflation factor (VIF) values provided in summary_corp_rep_ext$validity$vif_items.
# Collinearity analysis ----
summary_corp_rep_ext$validity$vif_itemsQUAL :
qual_1 qual_2 qual_3 qual_4 qual_5 qual_6 qual_7 qual_8
1.806 1.632 2.269 1.957 2.201 2.008 1.623 1.362
PERF :
perf_1 perf_2 perf_3 perf_4 perf_5
1.560 1.506 1.229 1.316 1.331
CSOR :
csor_1 csor_2 csor_3 csor_4 csor_5
1.560 1.487 1.735 1.556 1.712
ATTR :
attr_1 attr_2 attr_3
1.275 1.129 1.264
COMP :
comp_1 comp_2 comp_3
1.397 1.787 1.888
LIKE :
like_1 like_2 like_3
1.945 2.000 1.811
CUSA :
cusa
1
CUSL :
cusl_1 cusl_2 cusl_3
1.802 2.564 1.933
All indicator VIF values are below the conservative threshold of 3.0, indicating that collinearity is not a concern for any of the formative constructs in the extended corporate reputation model.
5.3.3 Statistical significance and relevance of the indicator weights
The next step for evaluating formatively specified constructs is to analyze the indicator weights’ significance and relevance. To do so, we follow the procedure outlined in Figure 5.
5.3.3.1 Indicator weights
We consider the significance of the indicator weights by means of bootstrapping (bootstrap_model()).
In bootstrap_model(), we use the following parameters:
Provide
corp_rep_pls_model_extas the seminr model to be evaluatedAssign n = 1000 bootstrap runs with
nboot = 1000. We use 1000 runs for a faster, initial estimation. For reporting the final results, the recommended number of 10,000 bootstrap samples should be used.Use
parallel::detectCores()to automatically detect the number of cores on your machine and use the maximum cores available. This allows for a faster estimation by using multiple (instead of only one) cores of your CPU.Use
seedto ensure that the results of a specific bootstrap can be reproduced on your software and hardware. Please note that even with a specified seed, the computations may differ bewteen various configurations of software and hardware meaning that your results might differ from ours.
We assign the output to the boot_corp_rep_ext object and apply summary() with a significance level of 5% (alpha = 0.05) for two-tailed testing.
We extract indicator weights results via sum_boot_corp_rep_ext$bootstrapped_weights.
# Bootstrap the model ----
# seminr_model is the SEMinR model to be bootstrapped
# nboot is the number of bootstrap iterations to run
# cores is the number of cpu cores to use in multicore bootstrapping
# parallel::detectCores() allows for using the maximum cores on your device
# seed is the seed to be used for making bootstrap replicable
boot_corp_rep_ext <- bootstrap_model(
seminr_model = corp_rep_pls_model_ext,
nboot = 1000,
cores = parallel::detectCores(),
seed = 123)Bootstrapping model using seminr...
SEMinR Model successfully bootstrapped
# Summarize the results of the bootstrap
# alpha sets the specified level for significance (i.e., 0.05)
sum_boot_corp_rep_ext <- summary(boot_corp_rep_ext, alpha = 0.05)
# Inspect the bootstrapping results for indicator weights
sum_boot_corp_rep_ext$bootstrapped_weights Original Est. Bootstrap Mean Bootstrap SD T Stat. 2.5% CI
qual_1 -> QUAL 0.202 0.207 0.061 3.338 0.093
qual_2 -> QUAL 0.041 0.040 0.051 0.808 -0.063
qual_3 -> QUAL 0.106 0.104 0.065 1.629 -0.027
qual_4 -> QUAL -0.005 -0.004 0.054 -0.085 -0.103
qual_5 -> QUAL 0.160 0.160 0.059 2.714 0.044
qual_6 -> QUAL 0.398 0.394 0.064 6.224 0.259
qual_7 -> QUAL 0.229 0.224 0.057 4.006 0.109
qual_8 -> QUAL 0.190 0.190 0.061 3.099 0.070
perf_1 -> PERF 0.468 0.465 0.068 6.887 0.326
perf_2 -> PERF 0.177 0.180 0.068 2.584 0.050
perf_3 -> PERF 0.194 0.189 0.054 3.603 0.089
perf_4 -> PERF 0.340 0.339 0.072 4.746 0.201
perf_5 -> PERF 0.199 0.197 0.062 3.184 0.075
csor_1 -> CSOR 0.306 0.300 0.083 3.671 0.139
csor_2 -> CSOR 0.037 0.035 0.069 0.536 -0.097
csor_3 -> CSOR 0.406 0.406 0.083 4.863 0.241
csor_4 -> CSOR 0.080 0.079 0.076 1.058 -0.076
csor_5 -> CSOR 0.416 0.416 0.089 4.662 0.245
attr_1 -> ATTR 0.414 0.415 0.071 5.848 0.273
attr_2 -> ATTR 0.201 0.196 0.063 3.165 0.074
attr_3 -> ATTR 0.658 0.655 0.062 10.549 0.537
comp_1 -> COMP 0.469 0.468 0.021 22.413 0.429
comp_2 -> COMP 0.365 0.366 0.017 21.421 0.335
comp_3 -> COMP 0.372 0.373 0.014 26.068 0.346
like_1 -> LIKE 0.419 0.420 0.014 29.343 0.393
like_2 -> LIKE 0.374 0.374 0.013 28.576 0.351
like_3 -> LIKE 0.363 0.363 0.014 26.477 0.337
cusa -> CUSA 1.000 1.000 0.000 . 1.000
cusl_1 -> CUSL 0.369 0.369 0.016 23.494 0.338
cusl_2 -> CUSL 0.420 0.421 0.015 28.972 0.395
cusl_3 -> CUSL 0.365 0.365 0.015 24.427 0.335
97.5% CI Bootstrap P Val
qual_1 -> QUAL 0.321 0.000
qual_2 -> QUAL 0.135 0.424
qual_3 -> QUAL 0.221 0.114
qual_4 -> QUAL 0.103 0.904
qual_5 -> QUAL 0.268 0.008
qual_6 -> QUAL 0.512 0.000
qual_7 -> QUAL 0.333 0.000
qual_8 -> QUAL 0.312 0.002
perf_1 -> PERF 0.594 0.000
perf_2 -> PERF 0.314 0.012
perf_3 -> PERF 0.304 0.000
perf_4 -> PERF 0.485 0.000
perf_5 -> PERF 0.323 0.000
csor_1 -> CSOR 0.467 0.000
csor_2 -> CSOR 0.173 0.626
csor_3 -> CSOR 0.563 0.000
csor_4 -> CSOR 0.220 0.286
csor_5 -> CSOR 0.607 0.000
attr_1 -> ATTR 0.544 0.000
attr_2 -> ATTR 0.322 0.002
attr_3 -> ATTR 0.770 0.000
comp_1 -> COMP 0.512 0.000
comp_2 -> COMP 0.400 0.000
comp_3 -> COMP 0.401 0.000
like_1 -> LIKE 0.448 0.000
like_2 -> LIKE 0.401 0.000
like_3 -> LIKE 0.390 0.000
cusa -> CUSA 1.000 0.000
cusl_1 -> CUSL 0.401 0.000
cusl_2 -> CUSL 0.452 0.000
cusl_3 -> CUSL 0.393 0.000
The output shows the following values which we use to evaluate the significance of the indicators:
Each row corresponds to one weight. Please note that weights are generated for all indicators (formative and reflective).
Original Est.shows each indicator’s original weight as estimated from the original dataset.Bootstrap Meanshows the mean of the weights from all bootstrap estimation.Bootstrap SDshows the standard error of the weights from all bootstrap estimation.T. Stat.shows the empirical t-value which is computed by dividing an indicator’s original weight (Original Est.) by its corresponding bootstrap standard error (Bootstrap SD).2.5% CIand97.5% CIshow the lower boundary (2.5% CI) and the upper boundary (97.5% CI) of the 95% confidence interval. Confidence intervals can be used for significance testing. Specifically, a null hypothesis H0 that a certain parameter, such as an indicator weight w1, equals zero (i.e., H0: w1 = 0) in the population is rejected at a given level alphs (α), if the corresponding (1 – α) % bootstrap confidence interval does not include zero. In other words, if a confidence interval does not include zero, we assume a significant effect.Bootstrap P Valshows the p-value.
The results indicate that all formative indicators are significant at a 5% level, except csor_2, csor_4, qual_2, qual_3, and qual_4.
For csor_2, csor_4, qual_2, qual_3, and qual_4, we can see that their 95% confidence interval includes zero and the p-value, correspondingly, is larger than 0.05. For example, for csor_2, the confidence interval ranges from -0.097 to 0.173 which includes 0 and the p-value of 0.626 also is non-significant at a 5% alpha level.
5.3.3.2 Indicator loadings
Following the procedure outlined in Figure 5 ((fig5?)), we now check the indicator loadings for the indicators with non-significant weights (i.e., csor_2, csor_4, qual_2, qual_3, and qual_4) by calling sum_boot_corp_rep_ext$bootstrapped_loadings.
# Inspect the bootstrapping results for indicator loadings
sum_boot_corp_rep_ext$bootstrapped_loadings Original Est. Bootstrap Mean Bootstrap SD T Stat. 2.5% CI
qual_1 -> QUAL 0.741 0.738 0.045 16.619 0.640
qual_2 -> QUAL 0.570 0.568 0.054 10.636 0.454
qual_3 -> QUAL 0.749 0.744 0.039 19.281 0.663
qual_4 -> QUAL 0.664 0.658 0.045 14.606 0.567
qual_5 -> QUAL 0.787 0.780 0.034 23.222 0.711
qual_6 -> QUAL 0.856 0.848 0.031 27.547 0.781
qual_7 -> QUAL 0.722 0.713 0.042 17.090 0.626
qual_8 -> QUAL 0.627 0.622 0.049 12.706 0.520
perf_1 -> PERF 0.846 0.839 0.035 24.055 0.766
perf_2 -> PERF 0.690 0.686 0.047 14.665 0.587
perf_3 -> PERF 0.573 0.568 0.051 11.156 0.466
perf_4 -> PERF 0.717 0.715 0.050 14.249 0.614
perf_5 -> PERF 0.638 0.634 0.059 10.760 0.507
csor_1 -> CSOR 0.771 0.761 0.050 15.397 0.652
csor_2 -> CSOR 0.571 0.562 0.060 9.432 0.437
csor_3 -> CSOR 0.838 0.830 0.043 19.467 0.737
csor_4 -> CSOR 0.617 0.610 0.057 10.745 0.492
csor_5 -> CSOR 0.848 0.841 0.043 19.726 0.749
attr_1 -> ATTR 0.754 0.753 0.051 14.919 0.645
attr_2 -> ATTR 0.506 0.501 0.066 7.609 0.362
attr_3 -> ATTR 0.891 0.887 0.033 26.678 0.816
comp_1 -> COMP 0.824 0.822 0.021 39.717 0.778
comp_2 -> COMP 0.821 0.821 0.020 40.457 0.781
comp_3 -> COMP 0.844 0.843 0.019 43.658 0.804
like_1 -> LIKE 0.880 0.880 0.016 55.828 0.847
like_2 -> LIKE 0.869 0.867 0.017 50.469 0.832
like_3 -> LIKE 0.844 0.844 0.019 44.828 0.803
cusa -> CUSA 1.000 1.000 0.000 . 1.000
cusl_1 -> CUSL 0.833 0.832 0.024 35.285 0.780
cusl_2 -> CUSL 0.917 0.917 0.010 89.030 0.894
cusl_3 -> CUSL 0.843 0.842 0.023 37.177 0.793
97.5% CI Bootstrap P Val
qual_1 -> QUAL 0.819 0.000
qual_2 -> QUAL 0.668 0.000
qual_3 -> QUAL 0.815 0.000
qual_4 -> QUAL 0.738 0.000
qual_5 -> QUAL 0.842 0.000
qual_6 -> QUAL 0.901 0.000
qual_7 -> QUAL 0.790 0.000
qual_8 -> QUAL 0.711 0.000
perf_1 -> PERF 0.902 0.000
perf_2 -> PERF 0.775 0.000
perf_3 -> PERF 0.664 0.000
perf_4 -> PERF 0.815 0.000
perf_5 -> PERF 0.739 0.000
csor_1 -> CSOR 0.852 0.000
csor_2 -> CSOR 0.671 0.000
csor_3 -> CSOR 0.904 0.000
csor_4 -> CSOR 0.716 0.000
csor_5 -> CSOR 0.917 0.000
attr_1 -> ATTR 0.841 0.000
attr_2 -> ATTR 0.626 0.000
attr_3 -> ATTR 0.946 0.000
comp_1 -> COMP 0.858 0.000
comp_2 -> COMP 0.856 0.000
comp_3 -> COMP 0.878 0.000
like_1 -> LIKE 0.907 0.000
like_2 -> LIKE 0.899 0.000
like_3 -> LIKE 0.879 0.000
cusa -> CUSA 1.000 0.000
cusl_1 -> CUSL 0.874 0.000
cusl_2 -> CUSL 0.935 0.000
cusl_3 -> CUSL 0.881 0.000
The resulting table is structurally similar to the table from previous estimation of indicator weights (sum_boot_corp_rep_ext$bootstrapped_weights) but shows results for the indicator loadings.
For csor_2, csor_4, qual_2, qual_3, and qual_4, all loadings are above the threshold value of 0.5 and are significant. Thus, we retain all indicators in the formatively measured constructs, even though not every indicator weight is significant.
6 Chapter 6: Evaluation of the structural model
In this chapter, we continue evaluating the extended corporate reputation model introduced in Chap. 5.
To initiate the analysis, we reload the necessary libraries and re-estimate the extended corporate reputation model.
# Load the SEMinR, SEMinRExtras libraries
library(seminr)
library(seminrExtras)
# Setup the plotting environment
oldpar <- par(mfrow = c(1,1))
# Load the data
corp_rep_data <- corp_rep_data
# Create measurement model ----
corp_rep_mm_ext <- constructs(
composite("QUAL", multi_items("qual_", 1:8), weights = mode_B),
composite("PERF", multi_items("perf_", 1:5), weights = mode_B),
composite("CSOR", multi_items("csor_", 1:5), weights = mode_B),
composite("ATTR", multi_items("attr_", 1:3), weights = mode_B),
composite("COMP", multi_items("comp_", 1:3)),
composite("LIKE", multi_items("like_", 1:3)),
composite("CUSA", single_item("cusa")),
composite("CUSL", multi_items("cusl_", 1:3))
)
# Create structural model ----
corp_rep_sm_ext <- relationships(
paths(from = c("QUAL", "PERF", "CSOR", "ATTR"), to = c("COMP", "LIKE")),
paths(from = c("COMP", "LIKE"), to = c("CUSA", "CUSL")),
paths(from = c("CUSA"), to = c("CUSL"))
)
# Estimate the model ----
corp_rep_pls_model_ext <- estimate_pls(
data = corp_rep_data,
measurement_model = corp_rep_mm_ext,
structural_model = corp_rep_sm_ext,
missing = mean_replacement,
missing_value = "-99")Generating the seminr model
All 344 observations are valid.
# Summarize the results of the model estimation
summary_corp_rep_ext <- summary(corp_rep_pls_model_ext)
# Bootstrap the model ----
boot_corp_rep_ext <- bootstrap_model(
seminr_model = corp_rep_pls_model_ext,
nboot = 1000,
cores = parallel::detectCores(),
seed = 123)Bootstrapping model using seminr...
SEMinR Model successfully bootstrapped
# Summarize the results of the bootstrap
summary_boot_corp_rep_ext <- summary(boot_corp_rep_ext,
alpha = 0.05)6.1 Assess collinearity issues in the structural model
We start by assessing collinearity issues in the structural model by inspecting the variance inflation factor (VIF) values for the structural model’s antecedents provided in summary_corp_rep_ext$vif_antecedents.
# Inspect the structural model collinearity VIF
summary_corp_rep_ext$vif_antecedentsCOMP :
QUAL PERF CSOR ATTR
3.487 2.889 2.083 2.122
LIKE :
QUAL PERF CSOR ATTR
3.487 2.889 2.083 2.122
CUSA :
COMP LIKE
1.686 1.686
CUSL :
COMP LIKE CUSA
1.716 1.954 1.412
We find that all VIFs are below the threshold of 5. Qual shows a value slighty above 3 (specifically {r}summary_corp_rep_ext$vif_antecedents$COMP["QUAL"]) which we consider unproblematic since it is a single occurence. Thus, we conclude that collinearity is not a concern for the structural model of the extended corporate reputation model.
6.2 Assess the model’s explanatory power
We next turn to the structural model assessment to evaluate the relevance and significance of the structural paths.
The following codes provides codes provides the following information about the structural model:
The structural path coefficients can be accessed by inspecting the
bootstrapped_pathselement nested in thesummary_corp_rep_extobject.The total effects (i.e., the sum of all direct and indirect effects that link to constructs) can be accessed by inspecting the
bootstrapped_total_pathselement nested in thesummary_corp_rep_extobject.The model’s explanatory power (R2) can be accessed by inspecting the
pathselement nested in thesummary_corp_rep_extobject.The model’s effect sizes (f2) can be accessed by inspecting the
fSquareelement nested in thesummary_corp_rep_extobject.
# Inspect the structural paths
summary_boot_corp_rep_ext$bootstrapped_paths
# Inspect the total effects
summary_boot_corp_rep_ext$bootstrapped_total_paths
# Inspect the model RSquares
summary_corp_rep_ext$paths
# Inspect the effect sizes
summary_corp_rep_ext$fSquare Original Est. Bootstrap Mean Bootstrap SD T Stat. 2.5% CI
QUAL -> COMP 0.430 0.431 0.065 6.603 0.303
QUAL -> LIKE 0.380 0.384 0.067 5.699 0.253
PERF -> COMP 0.295 0.301 0.064 4.611 0.173
PERF -> LIKE 0.117 0.123 0.073 1.613 -0.011
CSOR -> COMP 0.059 0.059 0.054 1.084 -0.044
CSOR -> LIKE 0.178 0.177 0.056 3.205 0.065
ATTR -> COMP 0.086 0.084 0.055 1.565 -0.018
ATTR -> LIKE 0.167 0.165 0.065 2.573 0.034
COMP -> CUSA 0.146 0.147 0.071 2.047 0.007
COMP -> CUSL 0.006 0.006 0.055 0.104 -0.104
LIKE -> CUSA 0.436 0.435 0.062 7.069 0.312
LIKE -> CUSL 0.344 0.343 0.056 6.175 0.231
CUSA -> CUSL 0.505 0.505 0.042 12.074 0.420
97.5% CI Bootstrap P Val
QUAL -> COMP 0.552 0.000
QUAL -> LIKE 0.514 0.000
PERF -> COMP 0.422 0.000
PERF -> LIKE 0.261 0.092
CSOR -> COMP 0.165 0.274
CSOR -> LIKE 0.282 0.002
ATTR -> COMP 0.194 0.102
ATTR -> LIKE 0.291 0.016
COMP -> CUSA 0.281 0.034
COMP -> CUSL 0.115 0.894
LIKE -> CUSA 0.555 0.000
LIKE -> CUSL 0.449 0.000
CUSA -> CUSL 0.586 0.000
The path coefficient output of summary_boot_corp_rep_ext$bootstrapped_paths shows the following metrics which we use to evaluate the significance of the path coefficient:
Each row corresponds to a specific path coefficient.
Original Est.shows each path coefficient as estimated from the original dataset.Bootstrap Meanshows the mean of a path coefficient from all bootstrap estimation.Bootstrap SDshows the standard error of a path coefficient from all bootstrap estimation.T. Stat.shows the empirical t-value which is computed by dividing the original path coefficient (Original Est.) by its corresponding bootstrap standard error (Bootstrap SD).2.5% CIand97.5% CIshow the lower boundary (2.5% CI) and the upper boundary (97.5% CI) of the 95% confidence interval that can be used for significance testing. Specifically, if a confidence interval does not include zero, we assume a significant effect.Bootstrap P Valshows the p-value.
For the paths from the exogenous constructs, we find that:
QUAL has a strong positive impact on both COMP (0.430) and LIKE (0.380), which are also both significant on a 5% alpha-level with p-values of p < .001. Please note that SEMinR displays such low p-values as 0.000. Such values should be reported as p < .001 since a p-value only approximatly reaches 0.
PERF shows a similar pattern of relationships with COMP (0.295) and LIKE (0.117). The path from PERF TO COMP is significant at a 5% alpha level with a p-value of p < .001 while the path from PERF to LIKE is not significant (p = .092)
CSOR has a positive, but comparatively small impact on COMP (0.059) and LIKE (0.178). The path from CSOR to COMP is not significant (p = .274) while the path from CSOR to LIKE is significant at a 5% alpha level with a p-value of p = .002.
ATTR has a positive but also a small impact on COMP (0.086) and LIKE (0.167). The path from ATTR to COMP is not significant (p = .102) while the path from ATTR to LIKE is significant at a 5% alpha level with a p-value of p = .016.
Similar interpretations can be reached if we interpret the confidence intervals instead of the p-values. For example, for the effect of QUAL to COMP 0 is clearly below the lower bound of the CI (CI95% = [0.303, 0.552]). Estimates that are not significant, such as the path coefficient for PERF to LIKE have a CI that includes 0 (CI95% = [-0.011, 0.261]).
Original Est. Bootstrap Mean Bootstrap SD T Stat. 2.5% CI
QUAL -> COMP 0.430 0.431 0.065 6.603 0.303
QUAL -> LIKE 0.380 0.384 0.067 5.699 0.253
QUAL -> CUSA 0.228 0.230 0.039 5.923 0.154
QUAL -> CUSL 0.248 0.251 0.044 5.679 0.165
PERF -> COMP 0.295 0.301 0.064 4.611 0.173
PERF -> LIKE 0.117 0.123 0.073 1.613 -0.011
PERF -> CUSA 0.094 0.098 0.040 2.373 0.024
PERF -> CUSL 0.089 0.094 0.045 1.968 0.009
CSOR -> COMP 0.059 0.059 0.054 1.084 -0.044
CSOR -> LIKE 0.178 0.177 0.056 3.205 0.065
CSOR -> CUSA 0.086 0.086 0.028 3.133 0.031
CSOR -> CUSL 0.105 0.105 0.033 3.166 0.038
ATTR -> COMP 0.086 0.084 0.055 1.565 -0.018
ATTR -> LIKE 0.167 0.165 0.065 2.573 0.034
ATTR -> CUSA 0.085 0.084 0.031 2.731 0.026
ATTR -> CUSL 0.101 0.100 0.038 2.652 0.028
COMP -> CUSA 0.146 0.147 0.071 2.047 0.007
COMP -> CUSL 0.079 0.081 0.069 1.155 -0.052
LIKE -> CUSA 0.436 0.435 0.062 7.069 0.312
LIKE -> CUSL 0.564 0.563 0.061 9.219 0.444
CUSA -> CUSL 0.505 0.505 0.042 12.074 0.420
97.5% CI Bootstrap P Val
QUAL -> COMP 0.552 0.000
QUAL -> LIKE 0.514 0.000
QUAL -> CUSA 0.310 0.000
QUAL -> CUSL 0.337 0.000
PERF -> COMP 0.422 0.000
PERF -> LIKE 0.261 0.092
PERF -> CUSA 0.179 0.010
PERF -> CUSL 0.180 0.032
CSOR -> COMP 0.165 0.274
CSOR -> LIKE 0.282 0.002
CSOR -> CUSA 0.138 0.002
CSOR -> CUSL 0.172 0.002
ATTR -> COMP 0.194 0.102
ATTR -> LIKE 0.291 0.016
ATTR -> CUSA 0.147 0.010
ATTR -> CUSL 0.178 0.014
COMP -> CUSA 0.281 0.034
COMP -> CUSL 0.213 0.270
LIKE -> CUSA 0.555 0.000
LIKE -> CUSL 0.676 0.000
CUSA -> CUSL 0.586 0.000
It is also important to consider the total effects to gain an idea of the impact of the four exogenous driver constructs on the outcome constructs CUSA and CUSL.
Of the four driver constructs, QUAL has the strongest total effect on CUSL (0.248), followed by CSOR (0.105), ATTR (0.101), and PERF (0.089). Please note that all of exogenous driver constructs’ total effects are significant at a 5% level (since all p-values are below the 5% alpha level).
COMP LIKE CUSA CUSL
R^2 0.631 0.558 0.292 0.562
AdjR^2 0.627 0.552 0.288 0.558
QUAL 0.430 0.380 . .
PERF 0.295 0.117 . .
CSOR 0.059 0.178 . .
ATTR 0.086 0.167 . .
COMP . . 0.146 0.006
LIKE . . 0.436 0.344
CUSA . . . 0.505
QUAL PERF CSOR ATTR COMP LIKE CUSA CUSL
QUAL 0.000 0.000 0.000 0.000 0.144 0.094 0.000 0.000
PERF 0.000 0.000 0.000 0.000 0.076 0.011 0.000 0.000
CSOR 0.000 0.000 0.000 0.000 0.005 0.034 0.000 0.000
ATTR 0.000 0.000 0.000 0.000 0.009 0.030 0.000 0.000
COMP 0.000 0.000 0.000 0.000 0.000 0.000 0.018 0.000
LIKE 0.000 0.000 0.000 0.000 0.000 0.000 0.159 0.138
CUSA 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.403
CUSL 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
We next consider the model’s explanatory power by analyzing the R2 of the endogenous constructs and the f2 effect size of the predictor constructs.
The R2 values of COMP (0.631), CUSL (0.562), and LIKE (0.558) can be considered moderate, whereas the R2 value of CUSA (0.292) is weak.
The f2 values for all combinations of endogenous constructs (represented by the columns) and corresponding predictor constructs (represented by the rows) show, for example, that LIKE has a medium effect size of 0.159 on CUSA and of 0.138 on CUSL. On the contrary, COMP has no effect on CUSA (0.018) or CUSL (0.000).
6.3 Assess the model’s predictive power
To assess the model’s predictive power, we can use the cross‐validated predictive ability test (CVPAT) which is a holdout-based procedure for comparing the predictive performance of a PLS path model with that of a linear regression model (LM) and an indicator averages model (IA) (Liengaard et al., 2021).
We use the assess_cvpat() function from the seminrExtras package to conduct the CVPAT assessment of the extended corporate reputation model (corp_rep_pls_model_ext).
The assess_cvpat() function requires the following parameters:
seminr_model: The SEMinR model to be assessed (here:corp_rep_pls_model_ext).testtype: The type of test to be performed. We use a one-tailed test with the alternative hypothesis that the PLS model has a greater predictive performance than the LM and IA models (i.e.,testtype = "greater").nboot: The number of bootstrap iterations to be performed. We use 2000 iterations for a faster, initial estimation. For reporting the final results, the recommended number of 10,000 bootstrap samples should be used.seed: The seed to be used for making the bootstrap replicable. Please note that even with a specified seed, the computations may differ bewteen various configurations of software and hardware meaning that your results might differ from ours.technique: The technique to be used for generating predictions. We use the default technique ofpredict_DAwhich generates predictions based on the direct antecedents (DA) approach.noFolds: The number of folds to be used in the cross-validation procedure. We use 10 folds.reps: The number of repetitions to be performed in the cross-validation procedure. We use 10 repetitions.
After estimating the CVPAT, we inspect the results for the comparison of the PLS model with the LM and IA models by calling assess_results$CVPAT_compare_LM and assess_results$CVPAT_compare_IA, respectively.
# Conduct CVPAT assessment of the established model
assess_results <- assess_cvpat(seminr_model = corp_rep_pls_model_ext,
testtype = "greater",
nboot = 2000,
seed = 123,
technique = predict_DA,
noFolds = 10,
reps = 10)
print(assess_results$CVPAT_compare_LM,
digits = 3) PLS Loss LM Loss Diff Boot T value Boot P Value
COMP 1.198 1.232 -0.034 1.156 0.124
LIKE 1.923 2.084 -0.162 4.014 0.000
CUSA 0.988 0.973 0.015 -0.612 0.729
CUSL 1.562 1.621 -0.058 3.510 0.000
Overall 1.418 1.477 -0.060 4.177 0.000
CVPAT as per Sharma et al. (2023).
print(assess_results$CVPAT_compare_IA,
digits = 3) PLS Loss IA Loss Diff Boot T value Boot P Value
COMP 1.198 2.023 -0.825 8.578 0.000
LIKE 1.923 3.103 -1.180 8.249 0.000
CUSA 0.988 1.374 -0.386 5.070 0.000
CUSL 1.562 2.663 -1.100 7.542 0.000
Overall 1.418 2.290 -0.873 10.269 0.000
CVPAT as per Sharma et al. (2023).
The results show that the PLS model has a significantly greater predictive performance than the IA model (p = 0.000).
For the comparision against the LM however, we find more mixed results. The global model also yields significantly better predictive power than the LM, indicating that the structural model contributes significant predictive power over and above the measurement model only. In terms of individual constructs, both COMP and CUSA, however, are not better predicted by our model than the LM with Δ: -0.034 (p = 0.124) and Δ: 0.015 (p = 0.729) for COMP and CUSA, respectively.
6.4 Model comparisons
We next turn to a model comparison. This step is optional and the analysis should be conducted if we have multiple theoretically or managerially justified candidate models.
In our demonstration, we compre the following models (Figure 6 ((fig6?)))
The following code builds the models:
# Conduct predictive model comparison
# Estimate alternative models
# Create measurement model ----
measurement_model <- constructs(
composite("QUAL", multi_items("qual_", 1:8), weights = mode_B),
composite("PERF", multi_items("perf_", 1:5), weights = mode_B),
composite("CSOR", multi_items("csor_", 1:5), weights = mode_B),
composite("ATTR", multi_items("attr_", 1:3), weights = mode_B),
composite("COMP", multi_items("comp_", 1:3)),
composite("LIKE", multi_items("like_", 1:3)),
composite("CUSA", single_item("cusa")),
composite("CUSL", multi_items("cusl_", 1:3))
)
# Create structural models
# Model 1
structural_model1 <- relationships(
paths(from = c("QUAL","PERF","CSOR","ATTR"), to = c("COMP", "LIKE")),
paths(from = c("COMP","LIKE"), to = c("CUSA", "CUSL")),
paths(from = "CUSA", to = c("CUSL"))
)
# Model 2
structural_model2 <- relationships(
paths(from = c("QUAL","PERF","CSOR","ATTR"), to = c("COMP", "LIKE", "CUSA")),
paths(from = c("COMP","LIKE"), to = c("CUSA", "CUSL")),
paths(from = "CUSA", to = c("CUSL"))
)
# Model 3
structural_model3 <- relationships(
paths(from = c("QUAL","PERF","CSOR","ATTR"),
to = c("COMP", "LIKE", "CUSA", "CUSL")),
paths(from = c("COMP","LIKE"), to = c("CUSA", "CUSL")),
paths(from = "CUSA", to = c("CUSL"))
)
# Estimate and summarize the models ----
pls_model1 <- estimate_pls(
data = corp_rep_data,
measurement_model = measurement_model,
structural_model = structural_model1,
missing_value = "-99"
)Generating the seminr model
All 344 observations are valid.
sum_model1 <- summary(pls_model1)
pls_model2 <- estimate_pls(
data = corp_rep_data,
measurement_model = measurement_model,
structural_model = structural_model2,
missing_value = "-99"
)Generating the seminr model
All 344 observations are valid.
sum_model2 <- summary(pls_model2)
pls_model3 <- estimate_pls(
data = corp_rep_data,
measurement_model = measurement_model,
structural_model = structural_model3,
missing_value = "-99"
)Generating the seminr model
All 344 observations are valid.
sum_model3 <- summary(pls_model3)For model comparison, we use three approaches:
Information-theoretic model selection criteria (IT criteria): IT criteria facilitate the comparison of models in terms of model fit and predictive power without requiring a holdout sample. Here, Schwarz’s (1978) Bayesian information criterion (BIC) achieves a good tradeoff between model fit and predictive power. Researchers should select the model that minimizes the value of BIC for a specific target construct. Differences in BIC values can, however, be small in practice, leading to model selection uncertainty. Akaike weights resolve this issue, by determining a model’s relative likelihood of being the data generation model, given the data and a set of competing models (Danks, Sharma, & Sarstedt, 2020). The higher the Akaike weights, the more likely it is that the selected model better represents the data generation model.
Predictive power: CVPAT can help assess whether an alternative model offers significantly higher out‐of‐sample predictive power than an established model.
Overfit ratio (OFR): The OFR is calculated as the ratio of in-sample predictive power to out-of-sample predictive power and indicates the relative loss in predictive power on training data versus unseen data. In other words, the OFR checks whether additional model complexity has affected model overfit. We recommend that the OFR should not be larger than 10% (Danks et al., 2024).
We focus our analysis on the CUSA construct as the immediate consequence of the two dimensions of corporate reputation (LIKE and COMP).
The following code assesses the IT criteria BIC and AIC by calling the it_criteria for each of the condidate models.
The results indicate that Model 1 is superior in terms of model fit. That is becausem the BIC values are lowest for Model 1 (-102.206) versus Model 2 (-93.965) and Model 3 (-97.401). The Akaike weight is also very high for Model 1 (0.904) compared to Model 2 (0.015) and Model 3 (0.082).
# Inspect the IT Criteria matrix of Model1
sum_model1$it_criteria COMP LIKE CUSA CUSL
AIC -333.825 -271.581 -113.728 -276.964
BIC -314.622 -252.378 -102.206 -261.602
# Subset the matrix to only return the BIC row and CUSA column
sum_model1$it_criteria["BIC", "CUSA"][1] -102.2062
# Collect the vector of BIC values for CUSA
itcriteria_vector <- c(sum_model1$it_criteria["BIC","CUSA"],
sum_model2$it_criteria["BIC","CUSA"],
sum_model3$it_criteria["BIC","CUSA"])
# Assign the model names to IT Criteria vector
names(itcriteria_vector) <- c("Model1", "Model2", "Model3")
# Inspect the IT Criteria vector for competing models
itcriteria_vector Model1 Model2 Model3
-102.20623 -93.96473 -97.40109
# Calculate the model BIC Akaike weights
compute_itcriteria_weights(itcriteria_vector) Model1 Model2 Model3
0.90357310 0.01466713 0.08175977
Next we compare Model1 and Model 3 in a CVPAT.
Please note that we use the function assess_cvpat_compare() and specify pls_model1 as the established_model and pls_model3 as an alternative model.
We however find that the established model does not yield significantly lower predictive error versus the alternative model overall (Δ-0.004. p = 0.359).
# Conduct CVPAT analysis ----
# Select the models for analysis and comparison
established_model <- pls_model1
alternative_model <- pls_model3
# Conduct CVPAT model comparison
compare_results <- assess_cvpat_compare(established_model = established_model,
alternative_model = alternative_model,
testtype = "greater",
nboot = 2000,
technique = predict_DA,
seed = 123,
noFolds = 10,
reps = 10)
print(compare_results,
digits = 3) Base Model Loss Alt Model Loss Diff Boot T value Boot P Value
COMP 1.198 1.218 -0.020 2.091 0.019
LIKE 1.923 1.926 -0.004 0.212 0.416
CUSA 0.988 0.973 0.015 -0.524 0.700
CUSL 1.562 1.569 -0.007 0.430 0.334
Overall 1.418 1.422 -0.004 0.362 0.359
CVPAT as per Sharma, Liengaard, Hair, Sarstedt, & Ringle, (2023).
Both models under comparison have identical endogenous constructs with identical measurement models.
Purely exogenous constructs can differ in regards to their relationships with both nomological
partners and measurement indicators.
As a last step, we assess the OFR for model 1 and model 3.
To do so, we use the predict_pls() function to each model object and apply summary() to get the objects that contain the OFR (predict_established, predict_alternative]. To display the OFR, we output the contents of predict_established$construct_error, respectively predict_alternative$construct_error and focus on the overfit row in the output.
# Calculate overfit ratio ----
predict_established <- summary(predict_pls(model = established_model))
predict_alternative <- summary(predict_pls(model = alternative_model))
# Overfit ratio for established model
predict_established$construct_error COMP LIKE CUSA CUSL
IS_MSE 0.36800108 0.44100070 0.70603720 0.4367325
IS_MAE 0.47052585 0.50553100 0.65591836 0.4781749
OOS_MSE 0.39071154 0.46543274 0.71604151 0.4443078
OOS_MAE 0.48278363 0.51782902 0.66001494 0.4821345
overfit 0.06171303 0.05540137 0.01416968 0.0173454
# Overfit ratio for alternative model
predict_alternative$construct_error COMP LIKE CUSA CUSL
IS_MSE 0.38670791 0.43553519 0.66888772 0.42814303
IS_MAE 0.48058468 0.50356657 0.63468175 0.47253053
OOS_MSE 0.40560867 0.45976228 0.70214427 0.45004365
OOS_MAE 0.49038194 0.51626100 0.64917392 0.48367538
overfit 0.04887605 0.05562602 0.04971918 0.05115258
The results also favor Model 1 since its OFR is notably smaller (0.014, i.e. 1.4%) than model 3’s OFR (0.050, i.e. 5%) and both OFRs do not exceed the stricter of the recommended thresholds of 10%.
7 Chapter 7: Moderation
Moderation describes a situation in which the relationship between two constructs is not constant but depends on the values of a third variable, referred to as a moderator variable. The moderator variable (or construct) changes the strength or even the direction of a relationship between two constructs in the model.
Specifically, we introduce perceived switching costs (SC) as a moderator variable that can be assumed to negatively influence the relationship between CUSA and CUSL (Fig. 7). We assume that the higher SC, the weaker the relationship between these two constructs. We use an extended form of Jones, Mothersbaugh, and Beatty’s (2000) scale and measure switching costs reflectively using four indicators (Tab. 5).
constructs_extMod <- rep("Switching Cost (SC)", 4)
ext_ModModelMM <- cbind(constructs_extMod,
c("switch_1","switch_2", "switch_3","switch_4"),
c("It takes me a great deal of time to switch to another company.",
"It costs me too much to switch to another company.",
"It takes a lot of effort to get used to a new company with its specific 'rules' and practices.",
"In general, it would be a hassle switching to another company."
))
colnames(ext_ModModelMM) <- c("construct", "variable name", "item")
knitr::kable(ext_ModModelMM,
caption = "**Tab. 5** Switching costs indicators")| construct | variable name | item |
|---|---|---|
| Switching Cost (SC) | switch_1 | It takes me a great deal of time to switch to another company. |
| Switching Cost (SC) | switch_2 | It costs me too much to switch to another company. |
| Switching Cost (SC) | switch_3 | It takes a lot of effort to get used to a new company with its specific ‘rules’ and practices. |
| Switching Cost (SC) | switch_4 | In general, it would be a hassle switching to another company. |
7.1 Creating the interaction term
Interaction terms are described in the measurement model functionconstructs() via interaction_term. We recommend using two-stage method which specifies the interaction term as the product of the latent scores of the independent construct and moderator variable. For specifying the measurement model, thus, we add the interaction term between the independent variable CUSA and the moderator variable SC and apply the two stage approach as follows: interaction_term(iv = "CUSA", moderator = "SC", method = two_stage).
# Load the SEMinR library
library(seminr)
# Load the data
corp_rep_data <- corp_rep_data
# Create the measurement model ----
corp_rep_mm_mod <- constructs(
composite("QUAL", multi_items("qual_", 1:8), weights = mode_B),
composite("PERF", multi_items("perf_", 1:5), weights = mode_B),
composite("CSOR", multi_items("csor_", 1:5), weights = mode_B),
composite("ATTR", multi_items("attr_", 1:3), weights = mode_B),
composite("COMP", multi_items("comp_", 1:3)),
composite("LIKE", multi_items("like_", 1:3)),
composite("CUSA", single_item("cusa")),
composite("SC", multi_items("switch_", 1:4)),
composite("CUSL", multi_items("cusl_", 1:3)),
interaction_term(iv = "CUSA", moderator = "SC", method = two_stage))Further, we add the path corresponding to the simple effect (i.e., a path from CS to CUSl) and the path corresponding to the interaction effect (i.e., CUSA*SC to CUSL) to the structural model. For this, we use paths(from = c("CUSA", "SC", "CUSA*SC"), to = c("CUSL")).
Next, we estimate the model with estimate_pls(), store it to corp_rep_pls_model_mod and summarize it to sum_corp_rep_mod. Further, we also apply bootstrapping and summarize the bootstrapped model with an alpha level of 5% (summary(boot_corp_rep_mod, alpha = 0.05)).
# Create the structural model ----
corp_rep_sm_mod <- relationships(
paths(from = c("QUAL", "PERF", "CSOR", "ATTR"), to = c("COMP", "LIKE")),
paths(from = c("COMP", "LIKE"), to = c("CUSA", "CUSL")),
paths(from = c("CUSA", "SC", "CUSA*SC"), to = c("CUSL"))
)
# Estimate the new model with moderator ----
corp_rep_pls_model_mod <- estimate_pls(
data = corp_rep_data,
measurement_model = corp_rep_mm_mod,
structural_model = corp_rep_sm_mod,
missing = mean_replacement,
missing_value = "-99"
)Generating the seminr model
All 344 observations are valid.
# Extract the summary
sum_corp_rep_mod <- summary(corp_rep_pls_model_mod)
# Bootstrap the model ----
boot_corp_rep_mod <- bootstrap_model(
seminr_model = corp_rep_pls_model_mod,
nboot = 1000)Bootstrapping model using seminr...
SEMinR Model successfully bootstrapped
# Summarize the results of the bootstrap
sum_boot_corp_rep_mod <- summary(boot_corp_rep_mod, alpha = 0.05)7.2 Model evaluation
In terms of the measurement model evaluation, al constructs still need to match the requirements outlined in Sections Section 4, Section 5, (structural?). However, there is no requirement to assess the measurement model of the interaction term (i.e., CUSA * SC) itself since it represents an auxiliary measurement and, thus, does not represent a distinct theoretical entity. Plase note that all measurement models, including the newly introduced SC construct, exhibit sufficient levels of reliability and validity.
In order to evaluate the moderating effect, we inspect the bootstrapped_paths element in the sum_boot_corp_rep_mod object and, to assess the moderating effect’s size, we inspect the paths f2 via sum_corp_rep_mod$fSquare.
# Inspect the bootstrapped structural paths
sum_boot_corp_rep_mod$bootstrapped_paths Original Est. Bootstrap Mean Bootstrap SD T Stat. 2.5% CI
QUAL -> COMP 0.430 0.429 0.065 6.637 0.302
QUAL -> LIKE 0.380 0.382 0.064 5.948 0.253
PERF -> COMP 0.295 0.301 0.063 4.716 0.174
PERF -> LIKE 0.117 0.123 0.069 1.694 -0.008
CSOR -> COMP 0.059 0.060 0.054 1.081 -0.045
CSOR -> LIKE 0.178 0.182 0.055 3.223 0.071
ATTR -> COMP 0.086 0.085 0.053 1.640 -0.014
ATTR -> LIKE 0.167 0.162 0.064 2.603 0.039
COMP -> CUSA 0.146 0.145 0.068 2.127 0.006
COMP -> CUSL -0.020 -0.019 0.059 -0.343 -0.129
LIKE -> CUSA 0.436 0.437 0.058 7.451 0.325
LIKE -> CUSL 0.319 0.318 0.057 5.594 0.212
CUSA -> CUSL 0.467 0.465 0.048 9.765 0.371
SC -> CUSL 0.071 0.073 0.058 1.224 -0.036
CUSA*SC -> CUSL -0.071 -0.073 0.032 -2.193 -0.140
97.5% CI Bootstrap P Val
QUAL -> COMP 0.555 0.000
QUAL -> LIKE 0.503 0.000
PERF -> COMP 0.427 0.000
PERF -> LIKE 0.262 0.076
CSOR -> COMP 0.170 0.270
CSOR -> LIKE 0.285 0.000
ATTR -> COMP 0.187 0.098
ATTR -> LIKE 0.285 0.008
COMP -> CUSA 0.273 0.040
COMP -> CUSL 0.105 0.738
LIKE -> CUSA 0.554 0.000
LIKE -> CUSL 0.436 0.000
CUSA -> CUSL 0.556 0.000
SC -> CUSL 0.185 0.194
CUSA*SC -> CUSL -0.009 0.028
# Inspect the fsquare
sum_corp_rep_mod$fSquare QUAL PERF CSOR ATTR COMP LIKE CUSA SC CUSA*SC CUSL
QUAL 0.000 0.000 0.000 0.000 0.144 0.094 0.000 0.000 0.000 0.000
PERF 0.000 0.000 0.000 0.000 0.076 0.011 0.000 0.000 0.000 0.000
CSOR 0.000 0.000 0.000 0.000 0.005 0.034 0.000 0.000 0.000 0.000
ATTR 0.000 0.000 0.000 0.000 0.009 0.030 0.000 0.000 0.000 0.000
COMP 0.000 0.000 0.000 0.000 0.000 0.000 0.018 0.000 0.000 0.000
LIKE 0.000 0.000 0.000 0.000 0.000 0.000 0.159 0.000 0.000 0.105
CUSA 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 .
SC 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 .
CUSA*SC 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.014
CUSL 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
The fSquare for certain relationships cannot be calculated as the model contains an interaction term and omitting either the antecedent or moderator in the interaction term will cause model estimation to fail
We find a negative interaction term for CUSA*SC on CUSL of –0.071 that is significant with a t-value of -2.191 and a p-value of 0.008. A corresponding simple effect of CUSA on CUSL has a path coefficient of 0.467 (t = 10.071, p < 0.001). These results suggest that a higher level of switching costs decrease the relationship between CUSA and CUSL. In terms of the effect size f², the moderating effect is small with f² = 0.014.
To better comprehend the results of the moderator analysis, we use the slope_analysis() function to visualize the two-way interaction effect. Therefore, we specify the model (moderated_model = corp_rep_pls_model_mod), the dependent variable (dv = "CUSL"), the moderator (moderator = "SC"), and the independent variable (iv = "CUSA") as well as the legend’s position (leg_place = "bottomright").
# Simple slope analysis plot
slope_analysis(
moderated_model = corp_rep_pls_model_mod,
dv = "CUSL",
moderator = "SC",
iv = "CUSA",
leg_place = "bottomright")The graph shows that the relationship between CUSA and CUSL is positive for all three lines. The negative moderating effect, however, shows itself at the slopes for the different levels of the moderator SC. Specifically:
higher levels of the moderator SC (i.e., the SC at +1SD line) correspond to a weaker effect of CUSA on CUSL.
lower levels of the moderator SC (i.e., the SC at -1SD line) correspond to a higher effect of CUSA on CUSL.
The results thus support the idea that higher switching costs (SC) decrease the effect of customer satisfaction (CUSA on customer loyalty (CUSL).
8 Chapter 8: Mediation
Mediation occurs when a construct, referred to as mediator construct, intervenes between two other related constructs. Direct effects are the relationships linking two constructs with a single arrow (p1, p2, and p3). Indirect effects represent a sequence of relationships with at least one intervening construct. Thus, an indirect effect is a sequence of two or more direct effects (p1 and p2) and is represented visually by multiple arrows.
Fig. 8 shows two mediation effects in the corporate reputation model, i.e. from COMP through CUSA to CUSL and from LIKE through CUSA to CUSL.
To initiate the analysis, we reload the necessary libraries and re-estimate the extended corporate reputation model.
# Load the SEMinR and seminrExtras libraries
library(seminr)
library(seminrExtras)
# Load the data
corp_rep_data <- corp_rep_data
# Create measurement model ----
corp_rep_mm_ext <- constructs(
composite("QUAL", multi_items("qual_", 1:8), weights = mode_B),
composite("PERF", multi_items("perf_", 1:5), weights = mode_B),
composite("CSOR", multi_items("csor_", 1:5), weights = mode_B),
composite("ATTR", multi_items("attr_", 1:3), weights = mode_B),
composite("COMP", multi_items("comp_", 1:3)),
composite("LIKE", multi_items("like_", 1:3)),
composite("CUSA", single_item("cusa")),
composite("CUSL", multi_items("cusl_", 1:3))
)
# Create structural model ----
corp_rep_sm_ext <- relationships(
paths(from = c("QUAL", "PERF", "CSOR", "ATTR"), to = c("COMP", "LIKE")),
paths(from = c("COMP", "LIKE"), to = c("CUSA", "CUSL")),
paths(from = c("CUSA"), to = c("CUSL"))
)
# Estimate the model ----
corp_rep_pls_model_ext <- estimate_pls(
data = corp_rep_data,
measurement_model = corp_rep_mm_ext,
structural_model = corp_rep_sm_ext,
missing = mean_replacement,
missing_value = "-99"
)Generating the seminr model
All 344 observations are valid.
# Summarize the results of the model estimation
summary_corp_rep_ext <- summary(corp_rep_pls_model_ext)
# Bootstrap the model ----
boot_corp_rep_ext <- bootstrap_model(
seminr_model = corp_rep_pls_model_ext,
nboot = 1000,
cores = parallel::detectCores(),
seed = 123
)Bootstrapping model using seminr...
SEMinR Model successfully bootstrapped
# Summarize the results of the bootstrap
summary_boot_corp_rep_ext <- summary(boot_corp_rep_ext,
alpha = 0.05)8.1 Testing mediating effects
The results for the indirect effects (\(\small p~1~*p~2~\)) can be found by inspecting the total_indirect_effects element within the summary_corp_rep_ext object.
Specific indirect paths can be evaluated for significance by using the specific_effect_significance() function. This function takes a bootstrapped model object (boot_corp_rep_ext), an antecedent construct name (from = "COMP, respectively from = "LIKE), a mediator construct name (through = "CUSA") and an outcome construct name (to = "CUSL") as arguments and returns the confidence interval (e.g. with alpha = 0.05) for the total indirect paths from the antecedent to the outcome construct.
Note that for serial mediation models, the through argument can take multiple mediating constructs as arguments (e.g. through = c("construct1", "construct2”)).
For example, the specific indirect effects for the paths from COMP through CUSA to CUSL and LIKE through CUSA to CUSL are:
# Inspect total indirect effects
summary_corp_rep_ext$total_indirect_effects QUAL PERF CSOR ATTR COMP LIKE CUSA CUSL
QUAL 0.000 0.000 0.000 0.000 0.000 0.000 0.228 0.248
PERF 0.000 0.000 0.000 0.000 0.000 0.000 0.094 0.089
CSOR 0.000 0.000 0.000 0.000 0.000 0.000 0.086 0.105
ATTR 0.000 0.000 0.000 0.000 0.000 0.000 0.085 0.101
COMP 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.074
LIKE 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.220
CUSA 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
CUSL 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
# Inspect indirect effects
specific_effect_significance(boot_corp_rep_ext,
from = "COMP",
through = "CUSA",
to = "CUSL",
alpha = 0.05) Original Est. Bootstrap Mean Bootstrap SD T Stat. 2.5% CI
COMP->CUSA->CUSL 0.074 0.074 0.037 2.013 0.003
97.5% CI Bootstrap P Val
COMP->CUSA->CUSL 0.146 0.034
specific_effect_significance(boot_corp_rep_ext,
from = "LIKE",
through = "CUSA",
to = "CUSL",
alpha = 0.05) Original Est. Bootstrap Mean Bootstrap SD T Stat. 2.5% CI
LIKE->CUSA->CUSL 0.220 0.220 0.037 5.966 0.149
97.5% CI Bootstrap P Val
LIKE->CUSA->CUSL 0.293 0.000
We find that the indirect effects are significant with
for COMP on CUSL, the coefficient for the indirect effect being 0.074 (p = .034)
for LIKE on CUSL , the coefficient for the indirect effect being 0.220 (p < .001)
Next, we consider both the indirect (\(\small p~1~*p~2~\)) and the direct effects (\(\small p~3~\)) to determine the mediation type, respectively the non-mediation type (Zhao et al., 2010). Zhao et al. (2010) identify three types of mediation:
- Complementary mediation: The indirect effect as well as the direct effect are significant and point in the same direction. The product of indirect and direct effects (\(\small p~1~*p~2~*p~3~\)) has a positive sign.
- Competitive mediation: The indirect effect as well as the direct effect are significant, but point in opposite directions. The product of indirect and direct effects (\(\small p~1~*p~2~*p~3~\)) has a negative sign.
- Indirect-only mediation: The indirect effect is significant but not the direct effect.
In addition, they characterize two types of non-mediation:
- Direct-only non-mediation: The direct effect is significant but not the indirect effect.
- No-effect non-mediation: Neither the direct nor the indirect effect are significant.
The direct effects (e.g. COMP on CUSL and LIKE on CUSL) can be accessed by the inspecting summary_corp_rep_ext$paths. The confidence intervals for the direct effects are stored in summary_boot_corp_rep_ext$bootstrapped_paths.
# Inspect the direct effects
summary_corp_rep_ext$paths COMP LIKE CUSA CUSL
R^2 0.631 0.558 0.292 0.562
AdjR^2 0.627 0.552 0.288 0.558
QUAL 0.430 0.380 . .
PERF 0.295 0.117 . .
CSOR 0.059 0.178 . .
ATTR 0.086 0.167 . .
COMP . . 0.146 0.006
LIKE . . 0.436 0.344
CUSA . . . 0.505
# Inspect the confidence intervals for direct effects
summary_boot_corp_rep_ext$bootstrapped_paths Original Est. Bootstrap Mean Bootstrap SD T Stat. 2.5% CI
QUAL -> COMP 0.430 0.431 0.065 6.603 0.303
QUAL -> LIKE 0.380 0.384 0.067 5.699 0.253
PERF -> COMP 0.295 0.301 0.064 4.611 0.173
PERF -> LIKE 0.117 0.123 0.073 1.613 -0.011
CSOR -> COMP 0.059 0.059 0.054 1.084 -0.044
CSOR -> LIKE 0.178 0.177 0.056 3.205 0.065
ATTR -> COMP 0.086 0.084 0.055 1.565 -0.018
ATTR -> LIKE 0.167 0.165 0.065 2.573 0.034
COMP -> CUSA 0.146 0.147 0.071 2.047 0.007
COMP -> CUSL 0.006 0.006 0.055 0.104 -0.104
LIKE -> CUSA 0.436 0.435 0.062 7.069 0.312
LIKE -> CUSL 0.344 0.343 0.056 6.175 0.231
CUSA -> CUSL 0.505 0.505 0.042 12.074 0.420
97.5% CI Bootstrap P Val
QUAL -> COMP 0.552 0.000
QUAL -> LIKE 0.514 0.000
PERF -> COMP 0.422 0.000
PERF -> LIKE 0.261 0.092
CSOR -> COMP 0.165 0.274
CSOR -> LIKE 0.282 0.002
ATTR -> COMP 0.194 0.102
ATTR -> LIKE 0.291 0.016
COMP -> CUSA 0.281 0.034
COMP -> CUSL 0.115 0.894
LIKE -> CUSA 0.555 0.000
LIKE -> CUSL 0.449 0.000
CUSA -> CUSL 0.586 0.000
The direct effect from COMP to CUSL is 0.006 (p = 0.894). Given the significant indirect effect and the non-significant direct effect, we conclude that the relationship between COMP and CUSL is fully mediated by CUSA.
Since the direct effect from LIKE to CUSL has a 0.344 path coefficient (p < .001) and a significant indirect effect, we conclude that CUSA partially mediates the effect of LIKE on CUSL.
To evaluate if CUSA acts as a complementary or competitive mediator for the effect of LIKE, respectively COMP, on CUSL, we determine whether the product of indirect and direct effects (\(\small p~1~*p~2~*p~3~\)) has a positive or negative sign.
We can subset the path matrix to access the path coefficients for p1, p2, and p3 (e.g. from LIKE to CUSA: summary_corp_rep_ext$paths[“LIKE”, “CUSA”].
# Calculate the sign of p1*p2*p3 for LIKE->CUSA->CUSL
summary_corp_rep_ext$paths["LIKE", "CUSL"] *
summary_corp_rep_ext$paths["LIKE","CUSA"] *
summary_corp_rep_ext$paths["CUSA","CUSL"][1] 0.07569007
# Calculate the sign of p1*p2*p3 for COMP->CUSA->CUSL
summary_corp_rep_ext$paths["COMP", "CUSL"] *
summary_corp_rep_ext$paths["COMP","CUSA"] *
summary_corp_rep_ext$paths["CUSA","CUSL"][1] 0.0004163559
All three paths for both mediation relationships are positive. Therefore CUSA acts as a complementary partial mediator between LIKE and CUSL.
8.2 Examining the mediation effect size
Next, we calculate the effect size υ by multiplying the squared path coefficients for each of the mediation relationships.
# Calculate the effect size v for LIKE->CUSA->CUSL
summary_corp_rep_ext$paths["LIKE","CUSA"]^2 *
summary_corp_rep_ext$paths["CUSA","CUSL"]^2[1] 0.04840573
# Calculate the effect size v for COMP->CUSA->CUSL
summary_corp_rep_ext$paths["COMP","CUSA"]^2 *
summary_corp_rep_ext$paths["CUSA","CUSL"]^2[1] 0.005402387
We find a small effect size (υ = 0.048) for LIKE to CUSL and a very small effect size (υ = 0.005) for COMP to CUSL.
8.3 Moderated (conditional) mediation
In the following section, we demonstrate a moderated mediation analysis as displayed in Fig. 9.
To set up the moderated mediation, we first rerun the code setting up the moderating effect (see Section 7).
# Conduct a moderated mediation analysis ----
# Create the measurement model ----
corp_rep_mm_mod <- constructs(
composite("QUAL", multi_items("qual_", 1:8), weights = mode_B),
composite("PERF", multi_items("perf_", 1:5), weights = mode_B),
composite("CSOR", multi_items("csor_", 1:5), weights = mode_B),
composite("ATTR", multi_items("attr_", 1:3), weights = mode_B),
composite("COMP", multi_items("comp_", 1:3)),
composite("LIKE", multi_items("like_", 1:3)),
composite("CUSA", single_item("cusa")),
composite("SC", multi_items("switch_", 1:4)),
composite("CUSL", multi_items("cusl_", 1:3)),
interaction_term(iv = "CUSA", moderator = "SC", method = two_stage))
# Create the structural model ----
corp_rep_sm_mod <- relationships(
paths(from = c("QUAL", "PERF", "CSOR", "ATTR"), to = c("COMP", "LIKE")),
paths(from = c("COMP", "LIKE"), to = c("CUSA", "CUSL")),
paths(from = c("CUSA", "SC", "CUSA*SC"), to = c("CUSL"))
)
# Estimate the new model with moderator ----
corp_rep_pls_model_mod <- estimate_pls(
data = corp_rep_data,
measurement_model = corp_rep_mm_mod,
structural_model = corp_rep_sm_mod,
missing = mean_replacement,
missing_value = "-99"
)Generating the seminr model
All 344 observations are valid.
# Extract the summary
sum_corp_rep_mod <- summary(corp_rep_pls_model_mod )
# Bootstrap the model ----
boot_corp_rep_mod <- bootstrap_model(
seminr_model = corp_rep_pls_model_mod,
seed = 123,
nboot = 1000)Bootstrapping model using seminr...
SEMinR Model successfully bootstrapped
Next, we use the code below to calculate and assess the indices of moderated mediation.
First, we calculate the point estimates for the relationship between COMP and CUSL by multiplying the path coefficnt from COMP to CUSA with the path coefficient from the interaction term *CUSA**SC* to CUSA via sum_corp_rep_mod$paths["COMP","CUSA"] * sum_corp_rep_mod$paths["CUSA*SC","CUSL"].
Using the same setup we also calculate the point estimates for the moderated mediation involving LIKE via sum_corp_rep_mod$paths["LIKE","CUSA"] * sum_corp_rep_mod$paths["CUSA*SC","CUSL"]
Second, we assign a helper function to get the p-value of the indes of moderated mediation.
In the third step, we compute the confidence interval for the index of moderated mediation and get its p-value.
To get the 95% confidence interval, we calculate the index of moderated mediation for each of the bootstrap runs via 1_p5_comp <- boot_corp_rep_mod$boot_path["COMP", "CUSA", ] * boot_corp_rep_mod$boot_path["CUSA*SC", "CUSL", ]. This operation yields a distribution from which we retrieve the 2.5% and 97.5% percentiles (in our case, we have nboot = 1000 estimates in this distribution). quantile(p1_p5_comp, probs = c(0.025, 0.975)) yields the corresponding confidence interval.
To get the p-value, we call our previously assigned function p_val(p1_p5_comp).
For LIKE, we can repeat this sequence.
# Index of moderated mediation ----
## Get the point estimate for the index of moderated mediation
# Compute p1*p5 for COMP
sum_corp_rep_mod$paths["COMP","CUSA"] *
sum_corp_rep_mod$paths["CUSA*SC","CUSL"][1] -0.01035297
# Compute p1*p5 for LIKE
sum_corp_rep_mod$paths["LIKE","CUSA"] *
sum_corp_rep_mod$paths["CUSA*SC","CUSL"][1] -0.03098968
## Get confidence intervals and p-values for the index of moderated mediation
# create a helper function to compute p-values
p_val <- function(x){
2*min(mean(x<=0), mean(x>=0))
}
# Compute p1*p5 and 95% confidence interval for COMP
p1_p5_comp <- boot_corp_rep_mod$boot_path["COMP", "CUSA", ] *
boot_corp_rep_mod$boot_path["CUSA*SC", "CUSL", ]
quantile(p1_p5_comp, probs = c(0.025, 0.975)) 2.5% 97.5%
-2.431237e-02 -5.395743e-05
# Compute the p-value of path p1*p5 for COMP
p_val(p1_p5_comp)[1] 0.048
# Compute p1*p5 and 95% confidence interval for LIKE
p1_p5_like <- boot_corp_rep_mod$boot_path["LIKE", "CUSA", ] *
boot_corp_rep_mod$boot_path["CUSA*SC", "CUSL", ]
quantile(p1_p5_like, probs = c(0.025, 0.975)) 2.5% 97.5%
-0.063572986 -0.004438182
# Compute the p-value of path p1*p5 for LIKE
p_val(p1_p5_like)[1] 0.014
For COMP, we find an index of moderated mediation of -0.010 that is (barely) significant with a confidence interval from -0.026 to -0.0002 and the bootstrap p-value of 0.048.
For LIKE the 95% confidence interval for the index of moderated mediation ranges from -0.064 to -0.006 and the bootstrap p-value 0.014.
9 Session info
sessionInfo()R version 4.5.2 (2025-10-31 ucrt)
Platform: x86_64-w64-mingw32/x64
Running under: Windows 11 x64 (build 26100)
Matrix products: default
LAPACK version 3.12.1
locale:
[1] LC_COLLATE=German_Germany.utf8 LC_CTYPE=German_Germany.utf8
[3] LC_MONETARY=German_Germany.utf8 LC_NUMERIC=C
[5] LC_TIME=German_Germany.utf8
time zone: Europe/Berlin
tzcode source: internal
attached base packages:
[1] stats graphics grDevices datasets utils methods base
other attached packages:
[1] seminrExtras_0.9.0 seminr_2.4.0
loaded via a namespace (and not attached):
[1] vctrs_0.7.1 nlme_3.1-168 cli_3.6.5 knitr_1.51
[5] rlang_1.1.7 xfun_0.56 otel_0.2.0 renv_1.1.7
[9] jsonlite_2.0.0 glue_1.8.0 htmltools_0.5.9 rmarkdown_2.30
[13] grid_4.5.2 evaluate_1.0.5 psych_2.5.6 visNetwork_2.1.4
[17] MASS_7.3-65 fastmap_1.2.0 yaml_2.3.12 lifecycle_1.0.5
[21] DiagrammeR_1.0.11 compiler_4.5.2 paran_1.5.4 RColorBrewer_1.1-3
[25] htmlwidgets_1.6.4 rstudioapi_0.18.0 lattice_0.22-7 digest_0.6.39
[29] mnormt_2.1.2 pillar_1.11.1 parallel_4.5.2 magrittr_2.0.4
[33] tools_4.5.2