Including moderators in SEM lavaan

245 views
Skip to first unread message

Dina Gant

unread,
May 19, 2022, 12:26:10 PM5/19/22
to lavaan
Hi, 
I am building an adapted UTAUT2 SEM model in lavaan. What I would like to do is include moderators (age, experience, e.literacy... etc) into the model and am not sure how to do this. Currently, my model looks like this:

______________________

A3 <- "PE_lat =~ PE1 + PE2 + PE3 + PE4 + PE5 + PE6 + PE7 + PE8
EE_lat =~ EE1 + EE2
SI_lat =~ SI1 + SI2
FC_lat =~ FC1 + FC2 + FC3
HM_lat =~ HM1 + HM2
SEff_lat =~ SEH1 + SET1
Barriers1_lat =~ BIR1 + BIR2 + BPI1 + BQC1
Barriers2_lat =~ BRI2 + BPI2 + BTR1 + BTR2
BIR1 ~~ BIR2
BI_lat =~ BI
BI_lat ~ PE_lat + EE_lat + SI_lat + FC_lat + HM_lat + SEff_lat + Barriers1_lat + Barriers2_lat + Age + Experience.code.binary + Gender + e.literacy"


#model cfa
A3.fit <- lavaan::cfa(model = A3, data = X20220421_export_for_R_coded, estimator = "DWLS")

#model fit
summary(A3.fit, standardized = TRUE, fit.measures = TRUE)

____________________________

I would like to test whether

  • Observed variables (Age (continuous), Gender (binary), Experience (binary) and e.literacy (ordinal))
  • Latent constructs (Barriers1_lat, Barriers2_lat, SEff_lat) 

act as moderators upon my UTAUT2 latent constructs (PE_lat, EE_lat, SI_lat, FC_lat and HM_lat). 
I would greatly appreciate your help on this issue!
Thank you,

Dina

Brett

unread,
May 19, 2022, 1:56:42 PM5/19/22
to lavaan
See this previous posting to this group for guidance on incorporating moderators: https://groups.google.com/g/lavaan/c/iP4LDqyjlLQ

Dina Gant

unread,
May 22, 2022, 1:51:38 PM5/22/22
to lavaan
Hi Brett, thank you for the quick response! 
It tried applying the indProd function, but am getting error codes. Here is my code:

_____

#Load excel
X20220421_export_for_R_coded <- read_excel("Paper 1/Stats/20220421_export-for-R-coded.xlsx")

#add interaction terms: (49:50 are columns for manifest variables EE1 and EE2; 94 column for Age)
EE_latxAge <- semTools::indProd(X20220421_export_for_R_coded, var1 = 49:50, var2 = 94, match = FALSE, meanC = TRUE, residualC = TRUE)

#Model A3 definition


A3 <- "PE_lat =~ PE1 + PE2 + PE3 + PE4 + PE5 + PE6 + PE7 + PE8
EE_lat =~ EE1 + EE2
SI_lat =~ SI1 + SI2
FC_lat =~ FC1 + FC2 + FC3
HM_lat =~ HM1 + HM2
SEff_lat =~ SEH1 + SET1
Barriers1_lat =~ BIR1 + BIR2 + BPI1 + BQC1
Barriers2_lat =~ BRI2 + BPI2 + BTR1 + BTR2
BIR1 ~~ BIR2
BI_lat =~ BI
BI_lat ~ PE_lat + EE_lat + SI_lat + FC_lat + HM_lat + SEff_lat + Barriers1_lat + Barriers2_lat + Age + Experience.code.binary + Gender + e.literacy + EE_latxAge"


#model cfa
A3.fit <- lavaan::cfa(model = A3, data = X20220421_export_for_R_coded, estimator = "DWLS")

#model fit
summary(A3.fit, standardized = TRUE, fit.measures = TRUE)

__________________________

I get following error codes at the model cfa step: 

"Error in lav_data_full(data = data, group = group, cluster = cluster,  :
  lavaan ERROR: missing observed variables in dataset: EE_latxAge"

Any idea what I might be doing wrong?
Kind regards and thank you

Dina

Terrence Jorgensen

unread,
May 23, 2022, 1:59:15 PM5/23/22
to lavaan
#add interaction terms: (49:50 are columns for manifest variables EE1 and EE2; 94 column for Age)
EE_latxAge <- semTools::indProd(X20220421_export_for_R_coded, var1 = 49:50, var2 = 94, match = FALSE, meanC = TRUE, residualC = TRUE)

You should not combine centering methods.  My advice is to use the default (double mean centering), or to use the orthogonalize() function for residual centering.  

As the ?indProd help page describes (see the Value section), you have saved a copy of your data, with new product terms added to it.

BI_lat ~ PE_lat + EE_lat + SI_lat + FC_lat + HM_lat + SEff_lat + Barriers1_lat + Barriers2_lat + Age + Experience.code.binary + Gender + e.literacy + EE_latxAge"

EE_latxAge is the name of the copy of your data, not the name of any of the (multiple) product indicators it contains.  Use str(EE_latxAge) or head(EE_latxAge) to see what your new data look like.

A3.fit <- lavaan::cfa(model = A3, data = X20220421_export_for_R_coded, estimator = "DWLS")

X20220421_export_for_R_coded is the object with your original data, which do not include product terms.

  lavaan ERROR: missing observed variables in dataset: EE_latxAge"

I assume you would like to model a latent construct that is the interaction between age and the latent variable EE_lat.  You will need to define that construct/interaction as measured by the product indicators in the data set EE_latxAge (or whatever you might choose to rename it).  It would be helpful to look through example applications on the "See Also" section, such as probe2WayRC() or probe2WayMC()

Terrence D. Jorgensen
Assistant Professor, Methods and Statistics
Research Institute for Child Development and Education, the University of Amsterdam

Dina Gant

unread,
May 29, 2022, 10:17:58 AM5/29/22
to lavaan
Hi Terrence,

thank you, that makes a lot of sense!
I've adjusted my code to create the interaction terms as follows: 

#creating interaction
X20220421_export_for_R_coded <- X20220421_export_for_R_coded %>% mutate(semTools::indProd(X20220421_export_for_R_coded, var1 = 49:50, var2 = 94, match = FALSE))

#model definition
A3 <- "PE_lat =~ PE1 + PE2 + PE3 + PE4 + PE5 + PE6 + PE7 + PE8
EE_lat =~ EE1 + EE2
SI_lat =~ SI1 + SI2
FC_lat =~ FC1 + FC2 + FC3
HM_lat =~ HM1 + HM2
SEff_lat =~ SEH1 + SET1
Barriers1_lat =~ BIR1 + BIR2 + BPI1 + BQC1
Barriers2_lat =~ BRI2 + BPI2 + BTR1 + BTR2
BIR1 ~~ BIR2
Int_EE_Age =~ EE1.Age + EE2.Age
BI_lat =~ BI
BI_lat ~ PE_lat + EE_lat + SI_lat + FC_lat + HM_lat + SEff_lat + Barriers1_lat + Barriers2_lat + Age + Experience.code.binary + Gender + e.literacy + Int_EE_Age"


#model cfa

A3.fit <- lavaan::cfa(model = A3, data = X20220421_export_for_R_coded, estimator = "DWLS")

#model fit
summary(A3.fit, standardized = TRUE, fit.measures = TRUE)

_____________________

The interaction term works without an issue, but when I try including it in my model R just starts computing and even after 30 minutes, I do not get any results (trying to run the model cfa). When I force stop I get following error/warning code:

In lav_data_full(data = data, group = group, cluster = cluster,  :
lavaan WARNING: some observed variances are (at least) a factor 1000 times larger than others; use varTable(fit) to investigate

This is not unexpected (age being continuous in years and my latent variable composed of scale items 0-5). How do I deal with this though?
Kind regards and again thank you for your help!

Dina

Brett

unread,
May 31, 2022, 3:24:35 AM5/31/22
to lavaan
Centering your predictors will not change their dispersion. You can rescale your predictors to similar variances by doing something akin to the below for each variable. Doing so will aid with numerical issues.

age_decades <- age / 10
age_0to1 <- (age - min(age)) / max(age)
age_sds <- age/sd(age)

By the way, highly recommend going through and changing your variable names (and more generally simplifying code as much as possible while reproducing your issue, preferably with public data or a simulated dataset) to make it easier to help. Hard to read your code at first. Here are tips.
Reply all
Reply to author
Forward
0 new messages