Search code examples
rr-lavaan

Continuous moderator and an interaction term with a latent variable in lavaan


I am a rather new user of lavaan and have been trying to build a moderator model with a continuous moderator and an interaction term with a latent variable. I would like to hear your feedback on my code and especially whether my approach seems appropriate regarding adding the interaction term afterwards (as it requires saving the latent variable in the data frame). Just to give a short description of my study: I investigate the relationship between stress and burnout, and whether social support moderates this association. Unfortunately, I don’t have the actual data yet, so I cannot give information on the possible warning/error messages.

#Creating the centered moderator variable SSMCOVID.c
Dataset$SSMCOVID.c <- scale(Dataset$SSMCOVID, scale = FALSE)

#Setting up the measurement model
RQ3 <- '
#Creating the independent TsM variable:
TsM =~ 1*SsM3mo + 1*SsM12mo + 1*SsM4y + 1*SsM4.5y

# Stress-burnout (independent-dependent):
PBAMCOVID ~ b1*TsM

#Support-burnout (moderator-dependent):
PBAMCOVID ~ b2*SSMCOVID.c '

fit.3 <- sem(RQ3, data = Dataset, estimator = 'MLR', missing = 'ML')
summary(fit.3, fit.measures=TRUE, standardized=TRUE)

#Extracting the predicted values of the model and adding them to the dataframe
data <- data.frame(Dataset, predict(fit.3))

#Creating a new variable with the interaction (note: dplyr package needed!)
data <- data %>%
              mutate(TsM_x_SSMCOVID.c = TsM * SSMCOVID.c)
              
#Testing the predefined interaction (moderation):
Moderation <- ' PBAMCOVID ~ b3*TsM_x_SSMCOVID.c '

fit.Mod <- sem(Moderation, data = data, estimator = 'MLR', missing = 'ML')
summary(fit.Mod, fit.measures=TRUE, standardized=TRUE)


Solution

  • Since you did not provide actual data, I will produce an example using the HolzingerSwineford1939 data frame. The library semTools has a function to make products of indicators using no centering, mean centering, double-mean centering, or residual centering:

    df_mod <- indProd(data = HolzingerSwineford1939, #create a new data.frame with the interaction indicators
                      var1 = paste0("x",c(1:3)), #interaction indicators from the first latent
                      var2 = paste0("x",c(4:6)), #interaction indicators from the second latent
                      match = T, #use match-paired approach (it produces the product of the first indicators of each variable, the product of the second indicator of each latent variable...
                      meanC = T, # mean centering the main effect indicator before making the products
                      residualC = T, #residual centering the products by the main effect indicators
                      doubleMC = T) #centering the resulting products
    
    head(df_mod[,(ncol(df_mod)-2):ncol(df_mod)]) #check the last three columns of the new data.frame
    
    
    model_latent_mod <- "
    latent_mod =~  
    x1.x4+
    x2.x5+
    x3.x6"
    
    fit_lat_mod <- cfa(model = model_latent_mod, data = df_mod) #run your latent interaction measurement model
    summary(object = fit_lat_mod, std=T, fit.m=T) #check the summary
    

    Then you just add this measurement model to your structural model. This approach is useful to produce interaction among latent variables, which I believe should be your case.

    If you want interaction between a latent variable and a manifest variable:

    
    model_latent_manifest_inter <- "
    latent_mod =~  
    x1
    x2
    x3
    
    ageyr ~latent_mod:x4
    "
    
    fit_lat_mod <- sem(model = model_latent_manifest_inter, data = HolzingerSwineford1939) #run your latent interaction measurement model
    summary(object = fit_lat_mod, std=T, fit.m=T) #check the summary