# Chapter 4: Structural Equation Models

### Example 2 on Structural equation modelling: The same model fitted separately for different countries

Fit the model considered in Example 1 separately for data from each of the countries in the ESS, and compare the results.

// Fitting the same structural equation model separately for
// each country, and collecting some of the results in a table.
// After fitting the model for one country,
// as in the previous exercise, this command reveals the
// labels of the coefficients, which are used below:
sem, coeflegend // Reveal the coefficient labels, used below
//
levelsof cntry, clean local(countries)
local n_c: word count `countries'
matrix results = J(`n_c',8,.)
matrix rownames results = `countries'
matrix colnames results = bEff pbEff bFair ///
pbFair bObey pbObey bMoral pbMoral
local i = 0
foreach c of local countries {
local ++i
display "Country: " "`c'"
quietly: sem ///
(Effective -> plcpvcr plccbrg plcarcr) ///
(ProcFair -> plcrspc plcfrdc plcexdc) ///
if cntry=="`c'", ///
var(Effective@1) var(ProcFair@1) ///
method(mlmv)
matrix b=e(b)
quietly: sem ///
(Obey -> bplcdc doplcsy dpcstrb) ///
(MoralAlign -> plcrgwr plcipvl gsupplc) ///
if cntry=="`c'", ///
var(Obey@1) var(MoralAlign@1) ///
method(mlmv)
matrix b1=e(b)
matrix b=b,b1
quietly: sem ///
(Cooperation -> caplcst widprsn wevdct) ///
if cntry=="`c'", ///
var(Cooperation@1) ///
method(mlmv)
matrix b1=e(b)
matrix b=b,b1
sem ///
(Effective -> plcpvcr plccbrg plcarcr) ///
(ProcFair -> plcrspc plcfrdc plcexdc) ///
(Obey -> bplcdc doplcsy dpcstrb) ///
(MoralAlign -> plcrgwr plcipvl gsupplc) ///
(Cooperation -> caplcst widprsn wevdct) ///
(Effective ProcFair -> Obey MoralAlign) ///
(Effective ProcFair Obey MoralAlign -> Cooperation) ///
if cntry=="`c'", ///
var(Effective@1) var(ProcFair@1) ///
var(e.Obey@1) var(e.MoralAlign@1) var(e.Cooperation@1) ///
cov(e.Obey*e.MoralAlign) method(mlmv) ///
from(b,skip) iter(100) nolog satopts(nolog) baseopts(nolog)
//
local converged=e(converged)
if(`converged'==1){
matrix results[`i',1] = _b[Cooperation:Effective]
quietly: test _b[Cooperation:Effective]==0
matrix results[`i',2] = r(p)
matrix results[`i',3] = _b[Cooperation:ProcFair]
quietly: test _b[Cooperation:ProcFair]==0
matrix results[`i',4] = r(p)
matrix results[`i',5] = _b[Cooperation:Obey]
quietly: test _b[Cooperation:Obey]==0
matrix results[`i',6] = r(p)
matrix results[`i',7] = _b[Cooperation:MoralAlign]
quietly: test _b[Cooperation:MoralAlign]==0
matrix results[`i',8] = r(p)
}
}
//
matlist results, format(%7.3f)

R commands:

# Fitting the same structural equation model separately for
# each country, and collecting some of the results in a table.
library(lavaan)
#
countries <- unique(ESS5Police\$cntry)
results <- matrix(NA,length(countries),8)
rownames(results) <- countries
colnames(results) <- c("bEff","pbEff","bFair","pbFair","bObey","pbObey","bMoral","pbMoral")
#
ModelSyntax <- '
Effective =~ plcpvcr + plccbrg + plcarcr
ProcFair =~ plcrspc + plcfrdc + plcexdc
Obey =~ bplcdc + doplcsy + dpcstrb
MoralAlign =~ plcrgwr + plcipvl + gsupplc
Cooperation =~ caplcst + widprsn + wevdct
#
Obey + MoralAlign ~ Effective + ProcFair
Cooperation ~ Effective + ProcFair + Obey + MoralAlign
#
Obey ~~ MoralAlign
'
# Loop over the countries, and collect results:
i <- 0
for(cntry in countries){
i <- i+1
cat("Country: ", cntry, "\n")
FittedModel.sem <- sem(model = ModelSyntax,
data = ESS5Police[ESS5Police\$cntry==cntry,],
std.lv = TRUE, meanstructure = TRUE,missing="ml")
print(summary(FittedModel.sem))
conv.tmp <- inspect(FittedModel.sem,"converged")
if(conv.tmp){
res.tmp <- parameterEstimates(FittedModel.sem)
res.tmp <- res.tmp[res.tmp\$lhs=="Cooperation"&res.tmp\$op=="~",]
results[i,1] <- res.tmp[res.tmp\$rhs=="Effective","est"]
results[i,2] <- res.tmp[res.tmp\$rhs=="Effective","pvalue"]
results[i,3] <- res.tmp[res.tmp\$rhs=="ProcFair","est"]
results[i,4] <- res.tmp[res.tmp\$rhs=="ProcFair","pvalue"]
results[i,5] <- res.tmp[res.tmp\$rhs=="Obey","est"]
results[i,6] <- res.tmp[res.tmp\$rhs=="Obey","pvalue"]
results[i,7] <- res.tmp[res.tmp\$rhs=="MoralAlign","est"]
results[i,8] <- res.tmp[res.tmp\$rhs=="MoralAlign","pvalue"]
}
}
print(round(results,3))

As one illustration of the results from this analysis, Table 4.1 shows the estimated regression coefficients and their levels of significance for the structural model for Co-operation with the police. Because these models were estimated separately for each of the countries rather than in one multigroup model, the scales of the latent variables are not here fixed to be comparable. The exact values of the regression coefficients can thus not be compared between the countries. However, we can compare the qualitative patterns of the results, for example the signs and levels of significance of the same coefficient in different countries.

There is a fair amount of variation in the levels of significance of the coefficients, in that each of the explanatory factors is a significant predictor of willingness to co-operate in many countries, but none of them in all countries. The variable which is significant in the largest number of countries is the person’s trust in the procedural fairness of the police. The directions of the associations are consistent in the sense that where a coefficient is significant it has the same sign in all the countries, with the one exception of trust in the effectiveness of the police which has a significantly negative coefficient in some countries and a significantly positive one in others.

Table 4.1: Estimated coefficients for the structural model for the factor on Willingness to co-operate with the police, estimated as part of the structural equation model shown in Figure 4.1, separately for each country in the ESS.

Coefficients in the model for
Co-operation:
Country Effectiveness Procedural
fairness
Obligation
to obey
Moral
alignment
Belgium (BE) -0.005 0.089 0.007 0.047
Bulgaria (BG) -0.028 0.148** 0.024 0.075**
Switzerland (CH) -0.078 0.197** 0.004 0.028
Cyprus (CY) -0.124* 0.249*** -0.050 -0.063
Czech Republic (CZ) 0.012 0.123** 0.023 0.086**
Germany (DE) 0.030 0.130*** -0.001 0.053*
Denmark (DK) -0.126** 0.123* 0.123*** 0.063
Estonia (EE) -0.091 0.243*** 0.054 0.102**
Spain (ES) -0.040 0.141* 0.046 -0.021
Finland (FI) -0.125** 0.137** 0.144*** 0.098**
France (FR) -0.163** 0.174** 0.071* 0.051
United Kingdom (GB) -0.089* 0.222*** 0.106*** -0.022
Greece (GR) 0.091* 0.074 -0.018 0.012
Croatia (HR) 0.066 0.138* -0.019 -0.034
Hungary (HU) -0.049 0.073 0.113*** 0.090*
Ireland (IE) 0.010 0.126** 0.013 0.124***
Israel (IL) -0.045 0.100* 0.137*** 0.008
Lithuania (LT) 0.107* -0.007 0.016 0.039
Netherlands (NL) -0.049 0.135** 0.104*** -0.005
Norway (NO) -0.115** 0.116 0.050 0.130**
Poland (PL) -0.094* 0.094 0.027 0.047
Portugal (PT) -0.029 0.023 0.005 -0.012
Russia (RU) 0.063 0.094* 0.016 0.022
Sweden (SE) -0.088* 0.166* 0.077* 0.047
Slovenia (SI) 0.137** 0.027 -0.100** -0.025
Slovakia (SK) -0.004 0.248*** 0.023 -0.054
Ukraine (UA) -0.052 0.106* -0.023 0.096**

Note: ***: p<0.001; **: p<0.01; *:p<0.05