Attitudes towards climate change in Europe
Attitudes towards climate change in Europe
Exercises
- Read in the ESS round 10 (2020) climate change attitudes data (see below under “Data”).
- In order not to spend most of your precious time waiting, filter the data to only include one country of your choice.
- Perform any exploratory data analyses you find necessary.
- Using
poLCA
, fit LCA models in which the seven participation items are used as indicators (so, excludeagea
,gndr
, andeisced
from the analysis for now). Try models with a different number of classes. Advice: try 1–6. - Use appropriate global fit measures, or any other criteria you prefer, to select the number of classes. Explain your choice.
- Look at local fit measures to assess the fit of your selected model.
- Create a profile plot for your selected model. (Hint: You can use the adjusted plotting code below.)
- Interpret your selected model by looking at the profiles. How would you label the classes?
- Create a classification table.
- Calculate the classification error and entropy \(R^2\).
- Refit your selected model, now while predicting class membership from
agea
, the square ofagea
,gndr
, andeisced
. - Use the
effects
library to plot the probability of each class as a function ofagea
,gndr
, andeisced
, according to your model. What do you conclude? (Hint: ifeffects
does not work, see the code below.) - BONUS: Investigate the distribution of classes over countries by redoing the analyses using all countries in the ess dataset
-
BONUS: Deal more appropriately with missing data, for example by using
mice
. You will need the original data from ESS.
Useful libraries
Data
Read the data from the European Social Survey, round 10 (2020).
An easy to read codebook copied from ESS is here: https://daob.nl/files/lca/ESS10-codebook.html. The full documentation is here: https://ess-search.nsd.no/en/study/172ac431-2a06-41df-9dab-c1fd8f3877e7.
-
ccnthum
- Climate change caused by natural processes, human activity, or both -
ccrdprs
- To what extent feel personal responsibility to reduce climate change -
wrclmch
- How worried about climate change -
testic37
- Imagine large numbers of people limit energy use, how likely reduce climate change -
testic38
- How likely, large numbers of people limit energy use -
testic39
- How likely, governments in enough countries take action to reduce climate change -
gndr
- Gender -
agea
- Age of respondent, calculated -
eisced
- Highest level of education, ES - ISCED
Note: The data have been preprocessed by ruthlessly subjecting them to na.omit
. I have also recoded eisced
to be missing except for values 1-7. Otherwise, the data are as-is from the ESS website.
ess10_climate <- read_csv("https://daob.nl/files/lca/ess10_climate.csv.gz")
ess10_climate |> rmarkdown::paged_table()
Visualization help
Because the assignment differs from the example in that this is polytomous data, and the number of categories differ, here is some (hopefully) helpful code to create profile plots.
```{r}
tidy(fit) %>% # from `broom` package
mutate(class = as.factor(class), outcome = as.factor(outcome)) %>%
ggplot(aes(outcome, estimate, group = class, color = class)) +
geom_point() + geom_line() + facet_wrap(~variable, scales = "free_x")+
geom_errorbar(aes(ymin = estimate - 2*std.error,
ymax = estimate + 2*std.error), width = 0.2) +
theme_bw() + scale_color_brewer(palette = "Set2")
```
Effects help
Unfortunately, effects
does not appear to function properly for this type of model. The code below could be helpful to create effects plots by hand. It assumes that the right-hand side of formula used was agea + I(agea^2) + gndr + eisced
.
The code below creates a dataframe with the “effects” of the various covariates based on the model estimates from fit
. This is also how effects
works and demonstrated within the poLCA
help file.
age_levels <- with(ess10_climate_it, {
seq(min(agea), max(agea), length = 20)
})
gndr_levels <- 1:2
eisced_levels <- 1:7
pidmat <- expand.grid(age_levels, gndr_levels, eisced_levels)
pidmat <- cbind(1, pidmat[,1], pidmat[,1]^2, pidmat[,2], pidmat[,3])
colnames(pidmat) <- rownames(coef(fit))
exb <- exp(pidmat %*% fit$coeff)
class_probs <- cbind(1, exb) / (1 + rowSums(exb))
colnames(class_probs) <- paste0("X", 1:ncol(class_probs))
df_effects <- cbind(pidmat[, -c(1,3)], class_probs) %>%
as_tibble %>%
pivot_longer(-(1:ncol(class_probs)), names_to = "Class")
df_effects
# A tibble: 840 × 5
agea gndr eisced Class value
<dbl> <dbl> <dbl> <chr> <dbl>
1 15 1 1 X1 0.363
2 15 1 1 X2 0.255
3 15 1 1 X3 0.382
4 18.9 1 1 X1 0.368
5 18.9 1 1 X2 0.252
6 18.9 1 1 X3 0.380
7 22.9 1 1 X1 0.372
8 22.9 1 1 X2 0.251
9 22.9 1 1 X3 0.378
10 26.8 1 1 X1 0.375
# … with 830 more rows
Example plot for agea
.
```{r}
%>%
df_effects group_by(agea, Class) %>%
summarize(pr = mean(value)) %>%
ggplot(aes(agea, pr, color = Class)) +
geom_line() +
scale_color_brewer(palette = "Set1") +
theme_bw()
```