MMM WT 2023/24: Exercise 8

Author
Affiliation
Susanne Adler

Institute for Marketing, Ludwig-Maximilians-University Munich

Set-up

Load relevant packages.

Show the code
library(seminr)
library(dplyr)
library(ggplot2)

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

(If necessary) do all relevant steps from the last exercise.

  • transform WTP to a numeric variable
  • set up the model (mm and sm)
  • estimate the model (model)
  • summarize the estimated model (model_sum)
  • bootstrap and summarize the model (model_boot and model_boot_sum)
Show the code
data$WP01_01_num <- gsub(pattern = ",", replacement = ".", data$WP01_01) %>% 
  as.numeric()

# 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"))
  )

## 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"))

# Estimate 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.
Show the code
# Summarize the model
model_sum <- summary(model)

# Bootstrap

model_boot <- bootstrap_model(
  seminr_model = model,
  nboot = 1000, # number of bootstrap iterations
  cores = parallel::detectCores(), # use all cores
  seed = 1001)
Bootstrapping model using seminr...
SEMinR Model successfully bootstrapped
Show the code
model_boot_sum <- summary(model_boot)

Mediation

reminder: indirect paths

Show the code
model_sum$total_indirect_effects
      SIC    PL    PQ    PI   WTP
SIC 0.000 0.000 0.000 0.355 0.176
PL  0.000 0.000 0.000 0.000 0.288
PQ  0.000 0.000 0.000 0.000 0.064
PI  0.000 0.000 0.000 0.000 0.000
WTP 0.000 0.000 0.000 0.000 0.000

test specific indirect paths (SIC -> PL -> PI and SIC -> PQ -> PI)

Show the code
specific_effect_significance(model_boot, 
                             from = "SIC", 
                             through = "PL", 
                             to = "PI", 
                             alpha = 0.05)
 Original Est. Bootstrap Mean   Bootstrap SD        T Stat.        2.5% CI 
    0.29694860     0.29837003     0.03927164     7.56140087     0.22694566 
      97.5% CI 
    0.37820012 
Show the code
specific_effect_significance(model_boot, 
                             from = "SIC", 
                             through = "PQ", 
                             to = "PI", 
                             alpha = 0.05)
 Original Est. Bootstrap Mean   Bootstrap SD        T Stat.        2.5% CI 
    0.05778152     0.05795351     0.02399739     2.40782492     0.01172313 
      97.5% CI 
    0.10580581 
Show an interpretation
# SIC -> PL -> PI: indirect effect positive and significant (indirect effect = 0.297, t = 7.56, CI= [0.227;0.378])

# SIC -> PQ -> PI: indirect effect positive and significant (indirect effect = 0.058, t = 2.41, CI= [0.011;0.106])

# indirect effect for SIC -> PL -> PI larger than for SIC -> PQ -> PI.

Recap: bootstrapped direct path significance

Show the code
model_boot_sum$bootstrapped_paths
            Original Est. Bootstrap Mean Bootstrap SD T Stat. 2.5% CI 97.5% CI
SIC  ->  PL         0.454          0.457        0.050   9.146   0.356    0.548
SIC  ->  PQ         0.398          0.401        0.053   7.468   0.292    0.501
SIC  ->  PI         0.044          0.043        0.058   0.761  -0.069    0.155
PL  ->  PI          0.654          0.654        0.057  11.568   0.540    0.771
PQ  ->  PI          0.145          0.144        0.056   2.587   0.030    0.244
PI  ->  WTP         0.441          0.445        0.051   8.715   0.344    0.540

Mediation type

Show an interpretation
# p1*p2 are significant (see above)
# p3 is n.s. with SIC -> PI (path coefficient = 0.044, t = 0.761, CI95% = [-0.069; 0.155])

## --> indirect only mediation

If p.3. would have been significant

Evaluate sign p1 * p2 * p3

Show the code
model_sum$paths["SIC", "PL"] *
  model_sum$paths["PL","PI"] * 
  model_sum$paths["SIC","PI"]
[1] 0.0130681
Show the code
model_sum$paths["SIC", "PQ"] *
  model_sum$paths["PQ","PI"] * 
  model_sum$paths["SIC","PI"]
[1] 0.002542846
Show an interpretation
# p3 is positive
# thus both indirect and direct effect point to the same direction
# --> complementary, partial mediation (applies to both mediations)

:::

Moderation

Model set up and estimation

Fist of all:

Influencer group is a character / string variable and cannot be used as a numeric variable in the seminr model.

Therefore, we have to specify influencer group as a numeric (0/1) variable to use it in the model.

To specify:

  • convert the InfluencerGroup (Emma or Franklin) variable to a numeric variable (1st to a factor then to a numeric variable)

  • use -1 to get 0 and 1 as numeric values for the InfluencerGroup_num variable.

Show the code
data$InfluencerGroup_num <- as.numeric(as.factor(data$InfluencerGroup))-1

table(data$InfluencerGroup_num, data$InfluencerGroup)
   
    Emma Franklin
  0  107        0
  1    0      116

Model set up

To do a moderation analysis, we have to set up the model again specifying the moderator

  • as an interaction term in the measurement model and

  • as a part of the structural model

Show the code
# Measurement model

mm_moderation <- 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")),
  composite("Influencer", single_item("InfluencerGroup_num")),
  interaction_term(iv = "SIC", moderator = "Influencer", method = two_stage)
)

# Structural model

sm_moderation <- relationships(
  paths(from = c("SIC", "Influencer", "SIC*Influencer"), to = c("PL", "PQ", "PI")),
  paths(from = "PL", to = "PI"),
  paths(from = "PQ", to = "PI"),
  paths(from = "PI", to = "WTP"))

Estimate and summarize the model

Show the code
model_moderation <- estimate_pls(data = data,
                      measurement_model = mm_moderation,
                      structural_model  = sm_moderation,
                      inner_weights = path_weighting)
Generating the seminr model
All 223 observations are valid.
Show the code
model_moderation_sum <- summary(model_moderation)

model_moderation_boot <- bootstrap_model(
  seminr_model = model_moderation,
  nboot = 1000, # number of bootstrap iterations
  cores = parallel::detectCores(), # use all cores
  seed = 1001)
Bootstrapping model using seminr...
SEMinR Model successfully bootstrapped
Show the code
model_moderation_boot_sum <- summary(model_moderation_boot)

Assess moderating paths

Show the code
model_moderation_boot_sum$bootstrapped_paths
                       Original Est. Bootstrap Mean Bootstrap SD T Stat.
SIC  ->  PL                    0.434          0.436        0.054   8.060
SIC  ->  PQ                    0.375          0.378        0.056   6.633
SIC  ->  PI                    0.043          0.042        0.057   0.743
Influencer  ->  PL            -0.239         -0.239        0.060  -3.996
Influencer  ->  PQ            -0.335         -0.335        0.054  -6.228
Influencer  ->  PI            -0.021         -0.027        0.047  -0.457
SIC*Influencer  ->  PL         0.068          0.065        0.055   1.253
SIC*Influencer  ->  PQ         0.146          0.144        0.060   2.438
SIC*Influencer  ->  PI        -0.031         -0.029        0.049  -0.620
PL  ->  PI                     0.653          0.654        0.058  11.241
PQ  ->  PI                     0.140          0.136        0.060   2.333
PI  ->  WTP                    0.441          0.445        0.051   8.707
                       2.5% CI 97.5% CI
SIC  ->  PL              0.321    0.536
SIC  ->  PQ              0.264    0.481
SIC  ->  PI             -0.071    0.150
Influencer  ->  PL      -0.353   -0.127
Influencer  ->  PQ      -0.437   -0.231
Influencer  ->  PI      -0.119    0.066
SIC*Influencer  ->  PL  -0.039    0.170
SIC*Influencer  ->  PQ   0.012    0.256
SIC*Influencer  ->  PI  -0.125    0.066
PL  ->  PI               0.534    0.771
PQ  ->  PI               0.015    0.247
PI  ->  WTP              0.344    0.540
Show an interpretation
# Focusing on the moderating effects (i.e., SIC*Influencer)
## There is no significant effect of SIC*Influencer on PL or PI. Specifically,
### SIC*Influencer -> PL (path coeffiecient = 0.068, t =  1.253, CI95% = [-0.039, 0.170]
### SIC*Influencer -> PI (path coeffiecient = -0.031, t = -0.620, CI95% = [-0.125, 0.066]

## However, we find a significant interaction effect for SIC*Influencer on PQ
### path coefficient = 0.146, t = 2.438, CI 95% = [0.012, 0.256]
## the path coefficient is positive which means that the relationship between PQ and SIC is higher for higher values of the moderator --> relationship is higher for Franklin (InfluencerGroup_num = 1) than for Emma (InfluencerGroup_num = 0).

Plot interaction effects

To plot the interaction effect, we extract the latent variable scores and plot the relationship for SIC to each variable (PQ, PI, PL) for both influencer groups.

Show the code
data$PQ_LV <- model_moderation$construct_scores[, "PQ"]
data$PL_LV <- model_moderation$construct_scores[, "PL"]
data$PI_LV <- model_moderation$construct_scores[, "PI"]
data$SIC_LV <- model_moderation$construct_scores[, "SIC"]

PQ

Show the code
ggplot(data,
       aes(SIC_LV, PQ_LV, color = InfluencerGroup)) +
  geom_count() + # use to get colored points per group
  geom_smooth(method = "lm") + # use to get the regression line
  theme_minimal()
`geom_smooth()` using formula = 'y ~ x'

PL

Show the code
ggplot(data,
       aes(SIC_LV, PL_LV, color = InfluencerGroup)) +
  geom_count() +
  geom_smooth(method = "lm") +
  theme_minimal()
`geom_smooth()` using formula = 'y ~ x'

PI

Show the code
ggplot(data,
       aes(SIC_LV, PI_LV, color = InfluencerGroup)) +
  geom_count() +
  geom_smooth(method = "lm") +
  theme_minimal()
`geom_smooth()` using formula = 'y ~ x'