First things first: setting up your environment

Remember: you always need to do this step first and include all the packages you need

# List of packages
packages <- c("tidyverse", "fst", "modelsummary", "viridis") # add any you need here

# Install packages if they aren't installed already
new_packages <- packages[!(packages %in% installed.packages()[,"Package"])]
if(length(new_packages)) install.packages(new_packages)

# Load the packages
lapply(packages, library, character.only = TRUE)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.4.4     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.0
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
## Loading required package: viridisLite
## [[1]]
##  [1] "lubridate" "forcats"   "stringr"   "dplyr"     "purrr"     "readr"    
##  [7] "tidyr"     "tibble"    "ggplot2"   "tidyverse" "stats"     "graphics" 
## [13] "grDevices" "utils"     "datasets"  "methods"   "base"     
## 
## [[2]]
##  [1] "fst"       "lubridate" "forcats"   "stringr"   "dplyr"     "purrr"    
##  [7] "readr"     "tidyr"     "tibble"    "ggplot2"   "tidyverse" "stats"    
## [13] "graphics"  "grDevices" "utils"     "datasets"  "methods"   "base"     
## 
## [[3]]
##  [1] "modelsummary" "fst"          "lubridate"    "forcats"      "stringr"     
##  [6] "dplyr"        "purrr"        "readr"        "tidyr"        "tibble"      
## [11] "ggplot2"      "tidyverse"    "stats"        "graphics"     "grDevices"   
## [16] "utils"        "datasets"     "methods"      "base"        
## 
## [[4]]
##  [1] "viridis"      "viridisLite"  "modelsummary" "fst"          "lubridate"   
##  [6] "forcats"      "stringr"      "dplyr"        "purrr"        "readr"       
## [11] "tidyr"        "tibble"       "ggplot2"      "tidyverse"    "stats"       
## [16] "graphics"     "grDevices"    "utils"        "datasets"     "methods"     
## [21] "base"
library(fst)
library(tidyverse)

Loading Data into R

Let’s load our data. We will first work with Spain

spain_data <- read.fst("spain_data.fst")

Task 1

Provide code and answer.

Prompt: in the tutorial, we calculated the average trust in others for France and visualized it. Using instead the variable ‘Trust in Parliament’ (trstplt) and the country of Spain (country file provided on course website), visualize the average trust by survey year. You can truncate the y-axis if you wish. Provide appropriate titles and labels given the changes. What are your main takeaways based on the visual (e.g., signs of increase, decrease, or stall)?

spain_data <- spain_data %>%
  mutate(
    trstplt = ifelse(trstplt %in% c(77, 88, 99), NA, trstplt), # set values 77, 88, and 99 to NA.
  )
table(spain_data$trstplt) 
## 
##    0    1    2    3    4    5    6    7    8    9   10 
## 5165 1830 2329 2441 2085 2890 1154  639  355   80   71
 spain_data$year <- NA # create a 'year' variable from the essround variable
replacements <- c(2002, 2004, 2006, 2008, 2010, 2012, 2014, 2016, 2018, 2020)
for(i in 1:10){
  spain_data$year[spain_data$essround == i] <- replacements[i]
}
table(spain_data$year)
## 
## 2002 2004 2006 2008 2010 2012 2014 2016 2018 2020 
## 1729 1663 1876 2576 1885 1889 1925 1958 1668 2283
trust_by_year <- spain_data %>%
  group_by(year) %>%
  summarize(mean_trust = mean(trstplt, na.rm = TRUE))
trust_by_year
## # A tibble: 10 × 2
##     year mean_trust
##    <dbl>      <dbl>
##  1  2002       3.41
##  2  2004       3.66
##  3  2006       3.49
##  4  2008       3.32
##  5  2010       2.72
##  6  2012       1.91
##  7  2014       2.23
##  8  2016       2.40
##  9  2018       2.55
## 10  2020       1.94
ggplot(trust_by_year, aes(x = year, y = mean_trust)) +
  geom_line(color = "blue", size = 1) +  # Line to show the trend
  geom_point(color = "red", size = 3) +  # Points to highlight each year's value
  labs(title = "Spain's Trust in Parliament (2002-2020)", 
       x = "Survey Year", 
       y = "Average Trust in Parliament") +
  ylim(0, 10) +  # Setting the y-axis limits from 0 to 10
  theme_minimal()
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

There is a decrease in the trust Spain has in the Parliament from 2002 to 2020.

Task 2

Provide answer only.

Prompt and question: Based on the figure we produced above called task2_plot, tell us: what are your main takeaways regarding France relative to Italy and Norway? Make sure to be concrete and highlight at least two important comparative trends visualized in the graph.

Compare the proportion of just ‘Yes’ to see if the trend across cohorts is distinct for France than it is for other countries – i.e., if it seems unique / if proportion stands relatively higher or lower than other countries.

Data preparation

norway_data <- read.fst("norway_data.fst")
france_data <- read.fst("france_data.fst")
italy_data <- read.fst("italy_data.fst")
# Combine data from three countries (France, Norway, Italy) into a single dataset
combined_countries_data <- bind_rows(
  france_data %>% mutate(cntry = "France"),  
  norway_data %>% mutate(cntry = "Norway"), 
  italy_data %>% mutate(cntry = "Italy")   
) %>%
  filter(!yrbrn %in% c(7777, 8888)) %>%  # Remove rows where 'yrbrn' (year born) is either 7777 or 8888 (likely missing data codes)
  mutate(
    yrbrn = ifelse(yrbrn > 2005, NA, yrbrn), # Replace 'yrbrn' values greater than 2005 with NA (as they are invalid)
    clsprty = ifelse(clsprty %in% c(7, 8, 9), NA, clsprty), # Replace 'clsprty' values of 7, 8, 9 with NA (considered as invalid or missing)
    clsprty = ifelse(clsprty == 2, 0, clsprty) # Convert 'clsprty' value of 2 to 0 (recoding for analysis purposes)
  )

# Compute proportions for 'clsprty' by 'yrbrn' for each country
clsprty_proportions_compare <- combined_countries_data %>%
  filter(!is.na(yrbrn) & yrbrn >= 1920 & !is.na(clsprty)) %>% # Filter out rows with NA in 'yrbrn' and 'clsprty', and where 'yrbrn' is earlier than 1920
  group_by(yrbrn, cntry) %>% # Group the data by 'yrbrn' (year born) and 'cntry' (country)
  summarise(yes_count = sum(clsprty), total_count = n(), .groups = 'drop') %>% # Summarise data to get count of 'clsprty' and total count per group
  mutate(proportion = yes_count / total_count) # Calculate the proportion of 'clsprty' in each group
# Visualizing the data
task2_plot <- ggplot(clsprty_proportions_compare, aes(x = yrbrn, y = proportion, color = cntry)) +  
  geom_point() +  
  geom_smooth(method = 'loess', se = FALSE) +  
  labs(
    title = "Proportion Saying 'Yes' to Feeling Close to a Party by Cohort",  # Title of the plot
    x = "Cohort",  
    y = "Proportion",  
    color = "Country"  
  ) +
  theme_minimal() +  
  scale_color_manual(values = c(
    "France" = "#1f77b4",  
    "Norway" = "#ff7f0e",  
    "Italy" = "#2ca02c"    
  )) +
  scale_y_continuous(limits = c(0, 1))  

# Display the plot
task2_plot
## `geom_smooth()` using formula = 'y ~ x'

My main takeaways regarding France relative to Italy and Norway is that Italy and France say ‘yes’ to feeling close to a party. Of the 3 countries, Norway is seen to display the highest feelings of closeness to their party, where they face a minor incline to a small decline. Italy in comparison reports a great decline in closenss to a party followed by France following closely behind.

Task 3

Provide code and answer.

Question: What is the marginal percentage of Italian men who feel close to a particular political party?

italy_data <- read.fst("italy_data.fst")
italy_data <- italy_data %>%
  mutate(
    gndr = case_when(
      gndr == 1 ~ "Male",
      gndr == 2 ~ "Female",
      TRUE ~ NA_character_  # Set anything that is not 1 or 2 to NA
    ),
    lrscale = case_when(
      lrscale %in% 1 ~ "yes",       
      lrscale %in% 2 ~ "no",    
      TRUE ~ NA_character_  # Moderate (4, 5, 6) and special codes (77, 88, 99) set to NA 
    )    
  ) 
lrscale_percentages <- italy_data %>%  
  filter(!is.na(lrscale), !is.na(gndr)) %>%  
  group_by(gndr, lrscale) %>%  
  summarise(count = n(), .groups = 'drop') %>%  
  mutate(percentage = count / sum(count) * 100)  

lrscale_percentages  
## # A tibble: 4 × 4
##   gndr   lrscale count percentage
##   <chr>  <chr>   <int>      <dbl>
## 1 Female no        225       33.7
## 2 Female yes       107       16.0
## 3 Male   no        248       37.1
## 4 Male   yes        88       13.2

Conclusion

13.2% of Italian men feel close to a particular political party.

Task 4

Provide code and output only.

Prompt: In the tutorial, we calculated then visualized the percentage distribution for left vs. right by gender for France. Your task is to replicate the second version of the visualization but for the country of Sweden instead.

sweden_data <- read.fst("sweden_data.fst")
sweden_data <- sweden_data %>%
  mutate(
    gndr = case_when(
      gndr == 1 ~ "Male",
      gndr == 2 ~ "Female",
      TRUE ~ NA_character_  # Set anything that is not 1 or 2 to NA
    ),
    lrscale = case_when(
      lrscale %in% 0:3 ~ "Left",       # Left-wing (0 to 3)
      lrscale %in% 7:10 ~ "Right",     # Right-wing (7 to 10)
      TRUE ~ NA_character_  # Moderating (4, 5, 6) and special codes (77, 88, 99) set to NA 
    )    
  ) 

Calculations

lrscale_percentages <- sweden_data %>% 
  filter(!is.na(lrscale), !is.na(gndr)) %>% 
  group_by(gndr, lrscale) %>%  
  summarise(count = n(), .groups = 'drop') %>%  
  mutate(percentage = count / sum(count) * 100) 

lrscale_percentages  
## # A tibble: 4 × 4
##   gndr   lrscale count percentage
##   <chr>  <chr>   <int>      <dbl>
## 1 Female Left     2296       23.0
## 2 Female Right    2530       25.3
## 3 Male   Left     2062       20.6
## 4 Male   Right    3107       31.1
lrscale_plot_v2 <- ggplot(lrscale_percentages, 
            aes(x = percentage,  
                y = reorder(gndr, -percentage),  
                fill = gndr)) +  

  # Create horizontal bar chart
  geom_col() +  
  coord_flip() +  

  guides(fill = "none") +  

  facet_wrap(~ lrscale, nrow = 1) +  

  # Labels and titles for the plot
  labs(x = "Percentage of Respondents",  # X-axis label
       y = NULL,  
       title = "Political Orientation by Gender",  
       subtitle = "Comparing the percentage distribution of left vs. right for Sweden (2002-2020)") +  

  theme(plot.title = element_text(size = 16, face = "bold"),  
        plot.subtitle = element_text(size = 12),  
        axis.title.y = element_blank(),  
        legend.position = "bottom")  

# Display the ggplot object
lrscale_plot_v2

Task 5

Provide code and answer: In Hungary, what is the conditional probability of NOT feeling close to any particular party given that the person lives in a rural area?

hungary_data <- read.fst("hungary_data.fst")
hungary_data <- hungary_data %>%
  mutate(
    gndr = case_when(
      gndr == 1 ~ "Male",
      gndr == 2 ~ "Female",
      TRUE ~ NA_character_  # Setting anything that is not 1 or 2 to NA
    ),
    clsprty = case_when(
      clsprty %in% 1 ~ "Yes",   
      clsprty %in% 2 ~ "No",    
      TRUE ~ NA_character_  # Moderate (4, 5, 6) and special codes (77, 88, 99) set to NA 
    )    
  ) 

Calculations

clsprty_hungary_percentages <- hungary_data %>%  
  filter(!is.na(clsprty), !is.na(gndr)) %>%  
  group_by(gndr, clsprty) %>%  
  summarise(count = n(), .groups = 'drop') %>%  
  mutate(percentage = count / sum(count) * 100)  
clsprty_hungary_percentages  
## # A tibble: 4 × 4
##   gndr   clsprty count percentage
##   <chr>  <chr>   <int>      <dbl>
## 1 Female No       5071       31.7
## 2 Female Yes      4008       25.0
## 3 Male   No       3608       22.5
## 4 Male   Yes      3334       20.8
# Recoding clsprty and geo variables, removing NAs
hungary_data <- hungary_data %>%
  mutate(
    geo = recode(as.character(domicil), 
                 '1' = "Urban", 
                 '2' = "Urban",
                 '3' = "Rural", 
                 '4' = "Rural", 
                 '5' = "Rural",
                 '7' = NA_character_,
                 '8' = NA_character_,
                 '9' = NA_character_)
  ) %>%
  filter(!is.na(clsprty), !is.na(geo)) 
# Calculate conditional probabilities, excluding NAs
cond <- hungary_data %>%
  count(clsprty, geo) %>%
  group_by(geo) %>%
  mutate(prob = n / sum(n))

cond
## # A tibble: 4 × 4
## # Groups:   geo [2]
##   clsprty geo       n  prob
##   <chr>   <chr> <int> <dbl>
## 1 No      Rural  6275 0.554
## 2 No      Urban  2395 0.512
## 3 Yes     Rural  5055 0.446
## 4 Yes     Urban  2283 0.488

Conclusion

In Hungary, the conditional probability of NOT feeling close to any particular party given that the person lives in a rural area is 55.4%