Attitudes towards climate change in Europe

Author

DL Oberski

Attitudes towards climate change in Europe

Exercises

  1. Read in the ESS round 10 (2020) climate change attitudes data (see below under “Data”).
  2. In order not to spend most of your precious time waiting, filter the data to only include one country of your choice.
  3. Perform any exploratory data analyses you find necessary.
  4. Using poLCA, fit LCA models in which the seven participation items are used as indicators (so, exclude agea, gndr, and eisced from the analysis for now). Try models with a different number of classes. Advice: try 1–6.
  5. Use appropriate global fit measures, or any other criteria you prefer, to select the number of classes. Explain your choice.
  6. Look at local fit measures to assess the fit of your selected model.
  7. Create a profile plot for your selected model. (Hint: You can use the adjusted plotting code below.)
  8. Interpret your selected model by looking at the profiles. How would you label the classes?
  9. Create a classification table.
  10. Calculate the classification error and entropy \(R^2\).
  11. Refit your selected model, now while predicting class membership from agea, the square of agea, gndr, and eisced.
  12. Use the effects library to plot the probability of each class as a function of agea, gndr, and eisced, according to your model. What do you conclude? (Hint: if effects does not work, see the code below.)
  13. BONUS: Investigate the distribution of classes over countries by redoing the analyses using all countries in the ess dataset
  14. 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()
```