5.3 At-Home Exercises
In these exercises, you will attempt to confirm the measurement model structure proposed in:
Kestilä, E. (2006). Is there demand for radical right populism in the Finnish electorate? Scandinavian Political Studies 29(3), 169–191. https://doi.org/10.1111/j.1467-9477.2006.00148.x
The data for this practical were collected during the first round of the European Social Survey (ESS). The ESS is a repeated cross-sectional survey administered in 32 European countries. The first wave was collected in 2002, and two new waves have been collected each year since. You can find more info and access the data at https://www.europeansocialsurvey.org.
The data we will analyze in this practical are contained in the file named ess_round1.rds. This file contains a processed subset of the ESS data. The following table describes the variables in this dataset.
| Variable | Type | Description |
|---|---|---|
| name | character | Title of dataset |
| essround | numeric | ESS round |
| edition | character | Edition |
| proddate | character | Production date |
| cntry | numeric | Country |
| idno | numeric | Respondent’s identification number |
| trstlgl | numeric | Trust in the legal system |
| trstplc | numeric | Trust in the police |
| trstun | numeric | Trust in the United Nations |
| trstep | numeric | Trust in the European Parliament |
| trstprl | numeric | Trust in country’s parliament |
| stfhlth | numeric | State of health services in country nowadays |
| stfedu | numeric | State of education in country nowadays |
| stfeco | numeric | How satisfied with present state of economy in country |
| stfgov | numeric | How satisfied with the national government |
| stfdem | numeric | How satisfied with the way democracy works in country |
| pltinvt | numeric | Politicians interested in votes rather than peoples opinions |
| pltcare | numeric | Politicians in general care what people like respondent think |
| trstplt | numeric | Trust in politicians |
| imsmetn | numeric | Allow many/few immigrants of same race/ethnic group as majority |
| imdfetn | numeric | Allow many/few immigrants of different race/ethnic group from majority |
| eimrcnt | numeric | Allow many/few immigrants from richer countries in Europe |
| eimpcnt | numeric | Allow many/few immigrants from poorer countries in Europe |
| imrcntr | numeric | Allow many/few immigrants from richer countries outside Europe |
| impcntr | numeric | Allow many/few immigrants from poorer countries outside Europe |
| qfimchr | numeric | Qualification for immigration: christian background |
| qfimwht | numeric | Qualification for immigration: be white |
| imwgdwn | numeric | Average wages/salaries generally brought down by immigrants |
| imhecop | numeric | Immigrants harm economic prospects of the poor more than the rich |
| imtcjob | numeric | Immigrants take jobs away in country or create new jobs |
| imbleco | numeric | Taxes and services: immigrants take out more than they put in or less |
| imbgeco | numeric | Immigration bad or good for country’s economy |
| imueclt | numeric | Country’s cultural life undermined or enriched by immigrants |
| imwbcnt | numeric | Immigrants make country worse or better place to live |
| imwbcrm | numeric | Immigrants make country’s crime problems worse or better |
| imrsprc | numeric | Richer countries should be responsible for accepting people from poorer countries |
| pplstrd | numeric | Better for a country if almost everyone share customs and traditions |
| vrtrlg | numeric | Better for a country if a variety of different religions |
| shrrfg | numeric | Country has more than its fair share of people applying refugee status |
| rfgawrk | numeric | People applying refugee status allowed to work while cases considered |
| gvrfgap | numeric | Government should be generous judging applications for refugee status |
| rfgfrpc | numeric | Most refugee applicants not in real fear of persecution own countries |
| rfggvfn | numeric | Financial support to refugee applicants while cases considered |
| rfgbfml | numeric | Granted refugees should be entitled to bring close family members |
| gndr | numeric | Gender |
| yrbrn | numeric | Year of birth |
| edulvl | ordered, factor | Highest level of education |
| eduyrs | numeric | Years of full-time education completed |
| polintr | ordered, factor | How interested in politics |
| lrscale | numeric | Placement on left right scale |
| country | factor | A factor version of the ‘cntry’ variable |
| sex | factor | A factor version of the ‘gndr’ variable |
5.3.1
Load the ess_round1.rds dataset.
- Inspect the data after loading to make sure everything went well.
Click to show code
library(tidySEM)
dataDir <- "data"
## Read the 'ess_round1.rds' data into a data frame called 'ess':
ess <- readRDS(here::here(dataDir, "ess_round1.rds"))
## Inspect the result:
dim(ess)## [1] 19690 52
Kestilä (2006) used principal components analysis to estimate the measurement model underlying thirteen ESS variables related to Trust in Politics. Based on the results of this PCA, Kestilä recommended the following three-factor structure.
Trust in Institutions
trstlgl: Trust in the legal systemtrstplc: Trust in the policetrstun: Trust in the United Nationstrustep: Trust in the European Parliamenttrustprl: Trust in country’s parliament
Satisfaction with the Political Situation
stfhlth: State of health services in country nowadaysstfedu: State of education in country nowadaysstfeco: How satisfied with present state of economy in countrystfgov: How satisfied with the national governmentstfdem: How satisfied with the way democracy works in country
Trust in Politicians
pltinvt: Politicians interested in votes rather than peoples opinionspltcare: Politicians in general care what people like respondent thinktrstplt: Trust in politicians
5.3.2
Define the lavaan model syntax for the three-factor CFA described above.
- Covary the three latent factors.
- Do not specify any mean structure.
- Save this model syntax as an object in your environment.
Click to show code
5.3.3
Estimate the CFA model you defined above, summarize the results, and evaluate the model fit.
- Use the
lavaan::cfa()function to estimate the model. - Use the fixed-factor method to identify the model.
- Otherwise, use the default settings for the
cfa()function. - Request the model fit indices by supplying the
fitMeasures = TRUEargument tosummary(). - Request the standardized parameter estimates by supplying the
standardized = TRUEargument tosummary().
Does the model fit the data well?
Click the code
## Load the lavaan package:
library(lavaan)
## Estimate the CFA model:
out_3f <- cfa(mod_3f, data = ess, std.lv = TRUE)
## Summarize the fitted model:
summary(out_3f, fit.measures = TRUE, standardized = TRUE)## lavaan 0.6-19 ended normally after 25 iterations
##
## Estimator ML
## Optimization method NLMINB
## Number of model parameters 29
##
## Used Total
## Number of observations 14778 19690
##
## Model Test User Model:
##
## Test statistic 10652.207
## Degrees of freedom 62
## P-value (Chi-square) 0.000
##
## Model Test Baseline Model:
##
## Test statistic 81699.096
## Degrees of freedom 78
## P-value 0.000
##
## User Model versus Baseline Model:
##
## Comparative Fit Index (CFI) 0.870
## Tucker-Lewis Index (TLI) 0.837
##
## Loglikelihood and Information Criteria:
##
## Loglikelihood user model (H0) -371404.658
## Loglikelihood unrestricted model (H1) -366078.555
##
## Akaike (AIC) 742867.317
## Bayesian (BIC) 743087.743
## Sample-size adjusted Bayesian (SABIC) 742995.583
##
## Root Mean Square Error of Approximation:
##
## RMSEA 0.108
## 90 Percent confidence interval - lower 0.106
## 90 Percent confidence interval - upper 0.109
## P-value H_0: RMSEA <= 0.050 0.000
## P-value H_0: RMSEA >= 0.080 1.000
##
## Standardized Root Mean Square Residual:
##
## SRMR 0.059
##
## Parameter Estimates:
##
## Standard errors Standard
## Information Expected
## Information saturated (h1) model Structured
##
## Latent Variables:
## Estimate Std.Err z-value P(>|z|) Std.lv Std.all
## institutions =~
## trstlgl 1.613 0.018 88.396 0.000 1.613 0.677
## trstplc 1.241 0.018 70.787 0.000 1.241 0.567
## trstun 1.498 0.018 82.522 0.000 1.498 0.642
## trstep 1.464 0.017 85.463 0.000 1.464 0.660
## trstprl 1.837 0.016 112.884 0.000 1.837 0.809
## satisfaction =~
## stfhlth 1.173 0.019 62.813 0.000 1.173 0.521
## stfedu 1.297 0.018 70.954 0.000 1.297 0.577
## stfeco 1.659 0.018 92.675 0.000 1.659 0.713
## stfgov 1.736 0.017 100.085 0.000 1.736 0.756
## stfdem 1.623 0.017 95.805 0.000 1.623 0.731
## politicians =~
## pltinvt 0.646 0.008 77.685 0.000 0.646 0.613
## pltcare 0.660 0.008 80.100 0.000 0.660 0.628
## trstplt 1.946 0.015 125.871 0.000 1.946 0.891
##
## Covariances:
## Estimate Std.Err z-value P(>|z|) Std.lv Std.all
## institutions ~~
## satisfaction 0.736 0.006 126.762 0.000 0.736 0.736
## politicians 0.872 0.004 198.326 0.000 0.872 0.872
## satisfaction ~~
## politicians 0.711 0.006 115.663 0.000 0.711 0.711
##
## Variances:
## Estimate Std.Err z-value P(>|z|) Std.lv Std.all
## .trstlgl 3.068 0.041 75.262 0.000 3.068 0.541
## .trstplc 3.248 0.041 80.037 0.000 3.248 0.678
## .trstun 3.197 0.041 77.141 0.000 3.197 0.588
## .trstep 2.776 0.036 76.243 0.000 2.776 0.564
## .trstprl 1.776 0.029 61.360 0.000 1.776 0.345
## .stfhlth 3.695 0.046 79.989 0.000 3.695 0.729
## .stfedu 3.368 0.043 77.916 0.000 3.368 0.667
## .stfeco 2.656 0.038 69.070 0.000 2.656 0.491
## .stfgov 2.264 0.035 64.201 0.000 2.264 0.429
## .stfdem 2.289 0.034 67.172 0.000 2.289 0.465
## .pltinvt 0.694 0.009 78.255 0.000 0.694 0.624
## .pltcare 0.668 0.009 77.562 0.000 0.668 0.605
## .trstplt 0.978 0.028 34.461 0.000 0.978 0.205
## institutions 1.000 1.000 1.000
## satisfaction 1.000 1.000 1.000
## politicians 1.000 1.000 1.000
Click for explanation
No, the model does not seem to fit the data well \((\chi^2 = 10652.21,\) \(\textit{df} = 62,\) \(p < 0.001,\) \(\textrm{RMSEA} = 0.108,\) \(\textrm{CFI} = 0.87,\) \(\textrm{SRMR} = 0.059)\).
The SRMR looks good, but one good looking fit statistic is not enough.
The RMSEA and CFI both indicate poor fit.
The \(\chi^2\) is highly significant, but we don’t care (especially when our sample size is \(N = 14778\)).
5.3.4
Consider the factor loadings for the Trust in Politicians factor.
- Do the loadings seem sensible?
- Do you notice any discrepancy between the raw and standardized estimates of these loadings?
- How would you explain this discrepancy (assuming you see one)?
Click for explanation
data.frame(
raw = lavInspect(out_3f, "estimates")$lambda[11:13, 3],
std = lavInspect(out_3f, "standardized")$lambda[11:13, 3]
)Hmm…something seem strange, but we need to be careful when evaluating these factor loadings.
- The raw loadings seem to suggest some pretty severe heterogeneity among the loadings of the Trust in Politicians factor.
- The standardized estimates don’t look too bad.
The only difference between these two versions of the loadings is the scale of the indicator variables.
- The indicators for the standardized loadings all have the same unit variance.
- The indicators for the raw loadings have their original scale.
Let’s check the scale of the raw indicator variables.
Well, there’s your problem! All the variables have an eleven-point scale except pltinvt and pltcare: they only have
five-point scales. So, the factor loadings for pltinvt and pltcare should be smaller than the factor loading for
trstplt. One unit of change in pltinvt or pltcare implies a large effect than one unit of change in trstplt
would.
Now, we will consider an alternative factor structure for the Trust in Politics CFA. We’ll go extremely simple by estimating a one-factor model wherein all Trust items are explained by a single latent variable.
5.3.5
Define the lavaan model syntax for a one-factor model of the Trust items.
- Save this syntax as an object in your environment.
Click to show code
5.3.6
Estimate the one-factor model, and summarize the results.
- Identify the scale using the fixed factor method.
- Don’t estimate any mean structure.
Does this model appear to fit better or worse than the three-factor model?
Click to show code
## Estimate the one factor model:
out_1f <- cfa(mod_1f, data = ess, std.lv = TRUE)
## Summarize the results:
summary(out_1f)## lavaan 0.6-19 ended normally after 21 iterations
##
## Estimator ML
## Optimization method NLMINB
## Number of model parameters 26
##
## Used Total
## Number of observations 14778 19690
##
## Model Test User Model:
##
## Test statistic 17667.304
## Degrees of freedom 65
## P-value (Chi-square) 0.000
##
## Parameter Estimates:
##
## Standard errors Standard
## Information Expected
## Information saturated (h1) model Structured
##
## Latent Variables:
## Estimate Std.Err z-value P(>|z|)
## political_trust =~
## trstlgl 1.516 0.018 83.138 0.000
## trstplc 1.174 0.017 67.425 0.000
## trstun 1.411 0.018 77.904 0.000
## trstep 1.378 0.017 80.594 0.000
## trstprl 1.792 0.016 111.470 0.000
## stfhlth 0.933 0.019 50.258 0.000
## stfedu 1.054 0.018 57.700 0.000
## stfeco 1.358 0.018 74.603 0.000
## stfgov 1.494 0.017 85.400 0.000
## stfdem 1.514 0.017 90.900 0.000
## pltinvt 0.580 0.008 69.442 0.000
## pltcare 0.600 0.008 72.700 0.000
## trstplt 1.793 0.015 118.311 0.000
##
## Variances:
## Estimate Std.Err z-value P(>|z|)
## .trstlgl 3.370 0.042 79.787 0.000
## .trstplc 3.410 0.041 82.311 0.000
## .trstun 3.451 0.043 80.749 0.000
## .trstep 3.019 0.038 80.272 0.000
## .trstprl 1.938 0.027 70.878 0.000
## .stfhlth 4.201 0.050 84.093 0.000
## .stfedu 3.941 0.047 83.419 0.000
## .stfeco 3.565 0.044 81.289 0.000
## .stfgov 3.044 0.038 79.326 0.000
## .stfdem 2.631 0.034 78.072 0.000
## .pltinvt 0.775 0.009 82.043 0.000
## .pltcare 0.743 0.009 81.579 0.000
## .trstplt 1.548 0.023 67.052 0.000
## political_trst 1.000
## Compare fit statistics:
data.frame(three_factor = fitMeasures(out_3f), one_factor = fitMeasures(out_1f)) |>
format(scientific = FALSE, digits = 3, drop0trailing = TRUE)Click for explanation
The one-factor model definitely seems to fit worse than the three-factor model.
End of At-Home Exercises