MMM WT 2023/24: Exercise 4

Author
Affiliation
Susanne Adler

Institute for Marketing, Ludwig-Maximilians-University Munich

Set-up

Load packages dplyr and seminr.

library(dplyr) # for data wrangling
library(seminr) # for PLS-SEM

data <- openxlsx::read.xlsx("MMM_influencer_data.xlsx")

The original data$WP01_01 is a character (not a numeric variable) since it was a free text in field in the survey.

class(data$WP01_01)
[1] "character"
data$WP01_01
  [1] "30"    "20"    "20"    "10"    "50"    "10"    "15"    "6"     "15"   
 [10] "35"    "0"     "15"    "30"    "1"     "5"     "20"    "5"     "5"    
 [19] "15"    "18"    "19,99" "30"    "15"    "0"     "35"    "10"    "19"   
 [28] "20"    "20"    "19,99" "0"     "6"     "0"     "10"    "5"     "15"   
 [37] "25"    "5"     "25"    "30"    "25"    "5"     "15"    "30"    "0"    
 [46] "5"     "0"     "2"     "0"     "0"     "50"    "0"     ",75"   "30"   
 [55] "39,99" "10"    "37"    "25"    "15"    "7"     "5"     "50"    "10"   
 [64] "20"    "20"    "6"     "10"    "15"    "20"    "50"    "12"    "18"   
 [73] "4"     "10"    "20"    "7"     "25"    "8"     "10"    "40"    "8"    
 [82] "30"    "78"    "10"    "40"    "10"    "5"     "40"    "5"     "80"   
 [91] "5"     "25"    "15"    "10"    "35"    "0"     "2"     "5"     "0"    
[100] "0"     "29,99" "8"     "19,99" "6"     "25"    "30"    "35"    "20"   
[109] "5"     "8"     "15"    "40"    "0"     "2"     "5"     "20"    "20"   
[118] "5"     "15"    "25"    "0"     "20"    "17"    "0"     "5"     "0"    
[127] "0"     "0"     "0"     "5"     "7"     "9"     "0"     "0"     "0"    
[136] "25"    "15"    "7"     "5"     "30"    "40"    "15"    "15"    "30"   
[145] "20"    "20"    "15"    "50"    "20"    "25"    "10"    "5"     "20"   
[154] "20"    "30"    "24"    "35"    "20"    "30"    "15"    "30"    "30"   
[163] "15"    "20"    "15"    "25"    "5"     "0"     "5"     "0"     "20"   
[172] "1"     "20"    "10"    "10"    "3"     "0"     "50"    "40"    "8"    
[181] "30"    "15"    "40"    "0"     "20"    "5"     "40"    "18"    "15"   
[190] "15"    "9,99"  "29"    "7"     "5"     "15"    "25"    "2"     "4"    
[199] "5"     "15"    "50"    "30"    "150"   "0"     "35"    "10"    "2"    
[208] "0"     "0"     "50"    "20"    "10"    "0"     "40"    "30"    "5"    
[217] "25"    "30"    "4"     "30"    "40"    "5"     "10"   

To use the variable in the SEM, we need to convert WP01_01 to a numeric variable. Since participants used a “,” and not “.” as a decimal seperator, we need to preprocess WP01_01 and replace “,” with “.” (–> gsub-command)

data$WP01_01_num <- gsub(pattern = ",", replacement = ".", data$WP01_01) %>% 
  as.numeric()

data$WP01_01_num
  [1]  30.00  20.00  20.00  10.00  50.00  10.00  15.00   6.00  15.00  35.00
 [11]   0.00  15.00  30.00   1.00   5.00  20.00   5.00   5.00  15.00  18.00
 [21]  19.99  30.00  15.00   0.00  35.00  10.00  19.00  20.00  20.00  19.99
 [31]   0.00   6.00   0.00  10.00   5.00  15.00  25.00   5.00  25.00  30.00
 [41]  25.00   5.00  15.00  30.00   0.00   5.00   0.00   2.00   0.00   0.00
 [51]  50.00   0.00   0.75  30.00  39.99  10.00  37.00  25.00  15.00   7.00
 [61]   5.00  50.00  10.00  20.00  20.00   6.00  10.00  15.00  20.00  50.00
 [71]  12.00  18.00   4.00  10.00  20.00   7.00  25.00   8.00  10.00  40.00
 [81]   8.00  30.00  78.00  10.00  40.00  10.00   5.00  40.00   5.00  80.00
 [91]   5.00  25.00  15.00  10.00  35.00   0.00   2.00   5.00   0.00   0.00
[101]  29.99   8.00  19.99   6.00  25.00  30.00  35.00  20.00   5.00   8.00
[111]  15.00  40.00   0.00   2.00   5.00  20.00  20.00   5.00  15.00  25.00
[121]   0.00  20.00  17.00   0.00   5.00   0.00   0.00   0.00   0.00   5.00
[131]   7.00   9.00   0.00   0.00   0.00  25.00  15.00   7.00   5.00  30.00
[141]  40.00  15.00  15.00  30.00  20.00  20.00  15.00  50.00  20.00  25.00
[151]  10.00   5.00  20.00  20.00  30.00  24.00  35.00  20.00  30.00  15.00
[161]  30.00  30.00  15.00  20.00  15.00  25.00   5.00   0.00   5.00   0.00
[171]  20.00   1.00  20.00  10.00  10.00   3.00   0.00  50.00  40.00   8.00
[181]  30.00  15.00  40.00   0.00  20.00   5.00  40.00  18.00  15.00  15.00
[191]   9.99  29.00   7.00   5.00  15.00  25.00   2.00   4.00   5.00  15.00
[201]  50.00  30.00 150.00   0.00  35.00  10.00   2.00   0.00   0.00  50.00
[211]  20.00  10.00   0.00  40.00  30.00   5.00  25.00  30.00   4.00  30.00
[221]  40.00   5.00  10.00

Model set up

Measurement model

mm <- constructs(
  composite("SIC", multi_items("SC02_0", 1:7)),
  composite("PL", multi_items("PL01_0", c(1, 4, 6, 7))),
  composite("PQ", multi_items("PQ01_0", 1:4)),
  composite("PI", multi_items("PI01_0", c(1, 2, 4, 5, 6))),
  composite("WTP", single_item("WP01_01_num"))
  )

Inspect the element: For each construct (e.g., “SIC”) mm shows

  • its indicators (e.g., “SC02_01”)
  • its mode (i.e., mode A for correlation weights = reflective measurement; mode B for regression weights = formative measurement)
mm
$composite
 [1] "SIC"     "SC02_01" "A"       "SIC"     "SC02_02" "A"       "SIC"    
 [8] "SC02_03" "A"       "SIC"     "SC02_04" "A"       "SIC"     "SC02_05"
[15] "A"       "SIC"     "SC02_06" "A"       "SIC"     "SC02_07" "A"      
attr(,"class")
[1] "character" "construct" "composite"

$composite
 [1] "PL"      "PL01_01" "A"       "PL"      "PL01_04" "A"       "PL"     
 [8] "PL01_06" "A"       "PL"      "PL01_07" "A"      
attr(,"class")
[1] "character" "construct" "composite"

$composite
 [1] "PQ"      "PQ01_01" "A"       "PQ"      "PQ01_02" "A"       "PQ"     
 [8] "PQ01_03" "A"       "PQ"      "PQ01_04" "A"      
attr(,"class")
[1] "character" "construct" "composite"

$composite
 [1] "PI"      "PI01_01" "A"       "PI"      "PI01_02" "A"       "PI"     
 [8] "PI01_04" "A"       "PI"      "PI01_05" "A"       "PI"      "PI01_06"
[15] "A"      
attr(,"class")
[1] "character" "construct" "composite"

$composite
[1] "WTP"         "WP01_01_num" "A"          
attr(,"class")
[1] "character" "construct" "composite"

attr(,"class")
[1] "list"              "measurement_model" "seminr_model"     

Structural model

sm <- relationships(
  paths(from = "SIC", to = c("PL", "PQ", "PI")),
  paths(from = "PL", to = "PI"),
  paths(from = "PQ", to = "PI"),
  paths(from = "PI", to = "WTP"))
sm
     source target
[1,] "SIC"  "PL"  
[2,] "SIC"  "PQ"  
[3,] "SIC"  "PI"  
[4,] "PL"   "PI"  
[5,] "PQ"   "PI"  
[6,] "PI"   "WTP" 
attr(,"class")
[1] "matrix"           "array"            "structural_model" "seminr_model"    

Estimate and plot the model:

model <- estimate_pls(data = data,
                      measurement_model = mm,
                      structural_model  = sm,
                      inner_weights = path_weighting)
Generating the seminr model
All 223 observations are valid.
plot(model)

Summarize the model

model_sum <- summary(model)

Measurement model assessment

Reliability statistics and convergent validity

model_sum$reliability
    alpha  rhoC   AVE  rhoA
SIC 0.930 0.943 0.705 0.942
PL  0.939 0.956 0.846 0.942
PQ  0.936 0.954 0.840 0.939
PI  0.945 0.958 0.821 0.949
WTP 1.000 1.000 1.000 1.000

Alpha, rhoC, and rhoA should exceed 0.7 while AVE should exceed 0.5
plot(model_sum$reliability)

Show an interpretation
# Internal consistency: Cronbach's alpha (alpha), composite reliability (rhoC, rhoA)
# --> All values exceed the threshold values of at least 0.70 required (0.80 for established constructs).
# --> Thus constructs are internally consistent (i.e., reliable).
# --> However, all values are also very high --> values higher than 0.90 (or 0.95) are often not desirable and indicate that the items are too redundant.

# Convergent validity: AVE
# --> all values > 0.5. Thus all constructs (on average) explain at least 50% of the assigned indicators’ variance.
# --> Constructs show sufficient convergent validity (i.e., constructs represent items sufficiently)

Indicator reliability

Inspect the outer loadings and square the loadigs to assess explained variance.

model_sum$loadings
              SIC    PL    PQ    PI   WTP
SC02_01     0.870 0.000 0.000 0.000 0.000
SC02_02     0.877 0.000 0.000 0.000 0.000
SC02_03     0.886 0.000 0.000 0.000 0.000
SC02_04     0.777 0.000 0.000 0.000 0.000
SC02_05     0.758 0.000 0.000 0.000 0.000
SC02_06     0.796 0.000 0.000 0.000 0.000
SC02_07     0.903 0.000 0.000 0.000 0.000
PL01_01     0.000 0.926 0.000 0.000 0.000
PL01_04     0.000 0.906 0.000 0.000 0.000
PL01_06     0.000 0.947 0.000 0.000 0.000
PL01_07     0.000 0.898 0.000 0.000 0.000
PQ01_01     0.000 0.000 0.921 0.000 0.000
PQ01_02     0.000 0.000 0.911 0.000 0.000
PQ01_03     0.000 0.000 0.906 0.000 0.000
PQ01_04     0.000 0.000 0.928 0.000 0.000
PI01_01     0.000 0.000 0.000 0.867 0.000
PI01_02     0.000 0.000 0.000 0.887 0.000
PI01_04     0.000 0.000 0.000 0.915 0.000
PI01_05     0.000 0.000 0.000 0.909 0.000
PI01_06     0.000 0.000 0.000 0.951 0.000
WP01_01_num 0.000 0.000 0.000 0.000 1.000
model_sum$loadings^2
              SIC    PL    PQ    PI   WTP
SC02_01     0.756 0.000 0.000 0.000 0.000
SC02_02     0.768 0.000 0.000 0.000 0.000
SC02_03     0.784 0.000 0.000 0.000 0.000
SC02_04     0.604 0.000 0.000 0.000 0.000
SC02_05     0.574 0.000 0.000 0.000 0.000
SC02_06     0.633 0.000 0.000 0.000 0.000
SC02_07     0.815 0.000 0.000 0.000 0.000
PL01_01     0.000 0.858 0.000 0.000 0.000
PL01_04     0.000 0.821 0.000 0.000 0.000
PL01_06     0.000 0.898 0.000 0.000 0.000
PL01_07     0.000 0.806 0.000 0.000 0.000
PQ01_01     0.000 0.000 0.849 0.000 0.000
PQ01_02     0.000 0.000 0.829 0.000 0.000
PQ01_03     0.000 0.000 0.820 0.000 0.000
PQ01_04     0.000 0.000 0.861 0.000 0.000
PI01_01     0.000 0.000 0.000 0.751 0.000
PI01_02     0.000 0.000 0.000 0.788 0.000
PI01_04     0.000 0.000 0.000 0.837 0.000
PI01_05     0.000 0.000 0.000 0.826 0.000
PI01_06     0.000 0.000 0.000 0.905 0.000
WP01_01_num 0.000 0.000 0.000 0.000 1.000
Show an interpretation
# All indicators show sufficient indicator reliability:
# --> all loadings > 0.707
# --> all squared loadings > 0.5 (i.e., construct accounts for > 50% of each indicator's variance)

Discriminant validity (HTMT)

model_sum$validity$htmt
      SIC    PL    PQ    PI WTP
SIC     .     .     .     .   .
PL  0.476     .     .     .   .
PQ  0.413 0.785     .     .   .
PI  0.423 0.825 0.682     .   .
WTP 0.140 0.463 0.485 0.449   .
Show an interpretation
# All HTMT point estimates meet the thresholds and are below 0.85 (resp. 0.9).
# --> Thus, they indicate discriminant validity between the latent variables (i.e., latent variables  measure different constructs).
# However, the HTMT for PL and PI  as well as for PL and PQ are rather high (HTMT(PI-PL) = .825, resp. HTMT(PQ-PL) = .785)
# Indicating that the constructs are partly related. This mirrors the factor analytic results (last exercise) that showed high interrelations between these constructs' items.