Last active
January 16, 2026 07:27
-
-
Save acbass49/8b69a5abf126afaa89eb1e4418b659e9 to your computer and use it in GitHub Desktop.
26 CES Political Compass Over Time
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| library(tidyverse) | |
| library(haven) | |
| library(sjlabelled) | |
| library(car) | |
| library(psych) # For factor analysis | |
| library(lavaan) | |
| library(ggrepel) | |
| library(clipr) | |
| library(binom) | |
| # 2008 | |
| load('./data/CES/data/2008.RData') | |
| # Check what objects were loaded | |
| ls() | |
| data <- x | |
| # Step 1: identify features | |
| econ <- c( | |
| 'CC309', | |
| 'CC311', | |
| 'CC312', | |
| 'CC316e', | |
| 'CC316h', | |
| 'CC316i', | |
| 'CC417', | |
| 'CC422' | |
| ) | |
| social <- c( | |
| 'CC310', # Abortion | |
| 'CC316f', # Gay marriage | |
| 'CC419_3', # read passage from constitution | |
| 'CC419_6', #photo id when vote | |
| 'CC313' # affirmative action | |
| ) | |
| features <- c( | |
| econ, | |
| social | |
| ) | |
| data <- data |> | |
| # Step 2: recode features to all be in same direction | |
| mutate( | |
| id = paste0('2008X', V100), | |
| CC309 = car::recode(sjlabelled::as_numeric(CC309), "2=1; 1=-1;3=-1;else=NA"), | |
| CC311 = car::recode(sjlabelled::as_numeric(CC311), "1=2;2=1;3=-1;4=-2;else=NA"), | |
| CC316e = car::recode(sjlabelled::as_numeric(CC316e), "1=-1;2=1;3=0;else=NA"), | |
| CC316h = car::recode(sjlabelled::as_numeric(CC316h), "1=1;2=-1;3=0;else=NA"), | |
| CC316i = car::recode(sjlabelled::as_numeric(CC316i), "1=-1;2=1;3=0;else=NA"), | |
| CC417 = car::recode(sjlabelled::as_numeric(CC417), "1=-2;2=-1;3=1;4=2;else=NA"), | |
| CC422 = car::recode(sjlabelled::as_numeric(CC422), "1=-1;2=1;3=0;else=NA"), | |
| CC310 = car::recode(sjlabelled::as_numeric(CC310), "1=2;2=1;3=-1;4=-2;else=NA"), | |
| CC316f = car::recode(sjlabelled::as_numeric(CC316f), "1=1;2=-1;3=0;else=NA"), | |
| CC419_3 = car::recode(sjlabelled::as_numeric(CC419_3), "1=1;2=-1;3=0;else=NA"), | |
| CC419_6 = car::recode(sjlabelled::as_numeric(CC419_6), "1=1;2=-1;3=0;else=NA"), | |
| CC313 = car::recode(sjlabelled::as_numeric(CC313), "1=-2;2=-1;3=1;4=2;else=NA") | |
| ) |> | |
| # Step 3: impute data at mean and standardize | |
| mutate(across(all_of(features), as.numeric)) |> | |
| mutate(across(all_of(features),\(x) tidyr::replace_na(x, mean(x, na.rm = TRUE)))) |> | |
| mutate(across(all_of(features), \(x) (x / max(x, na.rm = TRUE)))) | |
| data$social <- data |> | |
| select(all_of(social)) |> | |
| rowMeans(na.rm = TRUE) | |
| data$social <- (data$social - mean(data$social, na.rm = TRUE)) / sd(data$social, na.rm = TRUE) | |
| data$econ <- data |> | |
| select(all_of(econ)) |> | |
| rowMeans(na.rm = TRUE) | |
| data$econ <- (data$econ - mean(data$econ, na.rm = TRUE)) / sd(data$econ, na.rm = TRUE) | |
| data$V219 <- sjlabelled::as_labelled(data$V219) | |
| data$V211 <- sjlabelled::as_labelled(data$V211) | |
| data$V215 <- sjlabelled::as_labelled(data$V215) | |
| data$religion_rc <- dplyr::case_when( | |
| data$V219 == 1 & data$V211 == 2 ~ "Black Protestant", | |
| data$V219 == 1 & data$V215 == 1 ~ "Evangelical", | |
| data$V219 == 1 & data$V215 != 1 ~ "Mainline", | |
| data$V219 == 2 ~ "Catholic", | |
| data$V219 == 3 ~ "Mormon", | |
| data$V219 == 4 ~ "Orthodox", | |
| data$V219 == 5 ~ "Jewish", | |
| data$V219 == 6 ~ "Muslim", | |
| data$V219 == 7 ~ "Buddhist", | |
| data$V219 == 8 ~ "Hindu", | |
| data$V219 == 9 ~ "Atheist", | |
| data$V219 == 10 ~ "Agnostic", | |
| data$V219 == 11 ~ "Nothing in particular", | |
| TRUE ~ NA_character_ | |
| ) | |
| data$cluster <- dplyr::case_when( | |
| data$V218 == "Several times a day" & data$V216 == "Very important" & data$V217 %in% c("Once a week", "More than once a week") ~ "Devout Traditionalist", | |
| data$V217 %in% c("Once a week", "More than once a week", "Once or twice a month") ~ "Adaptive Believer", | |
| TRUE ~ "Cultural Mormon" | |
| ) | |
| plot <- data |> | |
| ggplot() + | |
| geom_jitter(aes(x = econ, y = social),alpha = 0.05, width = 0.3, height = 0.3) + | |
| geom_point(data = data |> | |
| group_by(religion_rc) |> | |
| summarise( | |
| mean_econ = weighted.mean(econ, na.rm = TRUE, w = V201), | |
| mean_soc = weighted.mean(social, na.rm = TRUE, w = V201), | |
| n = n() | |
| ) |> | |
| drop_na(), aes(x = mean_econ, y = mean_soc, size = n, color = religion_rc), alpha = 0.7) + | |
| geom_text_repel( | |
| data = data |> | |
| group_by(religion_rc) |> | |
| summarise( | |
| mean_econ = weighted.mean(econ, na.rm = TRUE, w = V201), | |
| mean_soc = weighted.mean(social, na.rm = TRUE, w = V201), | |
| n = n() | |
| ) |> | |
| drop_na(), aes(x = mean_econ, y = mean_soc, label = religion_rc, color = religion_rc), size = 2.5, max.overlaps = Inf, fontface = "bold") + | |
| xlim(-3,3) + | |
| ylim(-3,3) + | |
| theme( | |
| axis.ticks = element_blank(), | |
| axis.title = element_text(size = 14), | |
| axis.text.y = element_text(size = 10), | |
| axis.text.x = element_text(size = 10, margin = margin(t = -5)), | |
| plot.background = element_rect(fill = "grey95"), # Change entire plot background color here | |
| panel.background = element_blank(), | |
| text = element_text(face = "bold", family = "Cairo"), | |
| plot.title = element_text(size = 15, face = "bold"), | |
| plot.subtitle = element_text(size = 11), | |
| plot.title.position = "plot", | |
| plot.subtitle.position = "plot", | |
| legend.title = element_blank(), | |
| legend.background = element_blank(), | |
| legend.box.background = element_blank(), | |
| legend.key = element_blank(), | |
| legend.text = element_text(size = 5), | |
| panel.grid = element_blank(), | |
| legend.position = "none", | |
| panel.grid.major.y = element_line(color = "lightgrey", linetype = 'solid'), | |
| panel.grid.major.x = element_line(color = "lightgrey", linetype = 'solid'), | |
| plot.caption = element_text(size = 8,family = "Cairo") | |
| )+ | |
| guides(size = "none") + | |
| labs( | |
| title = "2008 Political Compass by Religion", | |
| subtitle = "Comprehensive Variable Set (n = 13 Policy Questions)", | |
| x = "Economic (Left - Right)", | |
| y = "Social (Libertarian - Authoritarian)", | |
| caption = "@mormon_metrics\nData: 2008 Cooperative Election Study (n=32,800)" | |
| ) | |
| ggsave("./images/26_political_compass_2008.png", plot, width = 1500, height = 1500, units = "px", dpi = 300) | |
| data |> | |
| filter(religion_rc == "Mormon") |> | |
| count(cluster) | |
| plot <- data |> | |
| filter(religion_rc == "Mormon") |> | |
| ggplot() + | |
| geom_jitter(aes(x = econ, y = social),alpha = 0.05, width = 0.3, height = 0.3) + | |
| geom_point(data = data |> | |
| filter(religion_rc == "Mormon") |> | |
| group_by(cluster) |> | |
| summarise( | |
| mean_econ = weighted.mean(econ, na.rm = TRUE, w = V201), | |
| mean_soc = weighted.mean(social, na.rm = TRUE, w = V201), | |
| n = n() | |
| ) |> | |
| drop_na(), aes(x = mean_econ, y = mean_soc, size = n, color = cluster), alpha = 0.7) + | |
| geom_text_repel( | |
| data = data |> | |
| filter(religion_rc == "Mormon") |> | |
| group_by(cluster) |> | |
| summarise( | |
| mean_econ = weighted.mean(econ, na.rm = TRUE, w = V201), | |
| mean_soc = weighted.mean(social, na.rm = TRUE, w = V201), | |
| n = n() | |
| ) |> | |
| drop_na(), aes(x = mean_econ, y = mean_soc, label = cluster, color = cluster), size = 2.5, max.overlaps = Inf, fontface = "bold") + | |
| xlim(-3,3) + | |
| ylim(-3,3) + | |
| scale_size_area(max_size = 8) + | |
| theme( | |
| axis.ticks = element_blank(), | |
| axis.title = element_text(size = 14), | |
| axis.text.y = element_text(size = 10), | |
| axis.text.x = element_text(size = 10, margin = margin(t = -5)), | |
| plot.background = element_rect(fill = "grey95"), # Change entire plot background color here | |
| panel.background = element_blank(), | |
| text = element_text(face = "bold", family = "Cairo"), | |
| plot.title = element_text(size = 15, face = "bold"), | |
| plot.subtitle = element_text(size = 11), | |
| plot.title.position = "plot", | |
| plot.subtitle.position = "plot", | |
| legend.title = element_blank(), | |
| legend.background = element_blank(), | |
| legend.box.background = element_blank(), | |
| legend.key = element_blank(), | |
| legend.text = element_text(size = 5), | |
| panel.grid = element_blank(), | |
| legend.position = "none", | |
| panel.grid.major.y = element_line(color = "lightgrey", linetype = 'solid'), | |
| panel.grid.major.x = element_line(color = "lightgrey", linetype = 'solid'), | |
| plot.caption = element_text(size = 8,family = "Cairo") | |
| )+ | |
| guides(size = "none") + | |
| labs( | |
| title = "2008 Political Compass by LDS Cluster", | |
| subtitle = "Comprehensive Variable Set (n = 13 Policy Questions)", | |
| x = "Economic (Left - Right)", | |
| y = "Social (Libertarian - Authoritarian)", | |
| caption = "@mormon_metrics\nData: 2008 Cooperative Election Study (n=629 LDS)" | |
| ) | |
| ggsave("./images/26_political_compass_2008_mormon.png", plot, width = 1500, height = 1500, units = "px", dpi = 300) | |
| # 2012 | |
| data <- load('./data/CES/data/2012.RData') | |
| data <- x | |
| social <- c( | |
| 'CC320', | |
| 'CC322_1', | |
| 'CC322_2', | |
| 'CC322_3', | |
| 'CC322_4', | |
| 'CC322_5', | |
| 'CC322_6', | |
| 'CC326', | |
| 'CC327', | |
| 'CC332E', | |
| 'CC332J', | |
| 'CC414_2', | |
| 'CC414_3', | |
| 'CC414_4', | |
| 'CC422a', | |
| 'CC422b' | |
| ) | |
| econ <- c( | |
| 'CC325', | |
| 'CC328', | |
| 'CC332A', | |
| 'CC332B', | |
| 'CC332C', | |
| 'CC332D', | |
| 'CC332F', | |
| 'CC332G', | |
| 'CC332H', | |
| 'CC332I', | |
| 'CC414_2', | |
| 'CC414_3' | |
| ) | |
| features <- c( | |
| econ, | |
| social | |
| ) | |
| data <- data |> | |
| # Step 2: recode features to all be in same direction | |
| mutate( | |
| #social | |
| CC320 = car::recode(sjlabelled::as_numeric(CC320), "1=1; 2=-1;3=0;else=NA"), | |
| CC322_1 = car::recode(sjlabelled::as_numeric(CC322_1), "1=1;2=-1;else=NA"), | |
| CC322_2 = car::recode(sjlabelled::as_numeric(CC322_2), "1=1;2=-1;else=NA"), | |
| CC322_3 = car::recode(sjlabelled::as_numeric(CC322_3), "1=1;2=-1;else=NA"), | |
| CC322_4 = car::recode(sjlabelled::as_numeric(CC322_4), "1=1;2=-1;else=NA"), | |
| CC322_5 = car::recode(sjlabelled::as_numeric(CC322_5), "1=1;2=-1;else=NA"), | |
| CC322_6 = car::recode(sjlabelled::as_numeric(CC322_6), "1=1;2=-1;else=NA"), | |
| CC326 = car::recode(sjlabelled::as_numeric(CC326), "1=2;2=1;3=-1;4=-2;else=NA"), | |
| CC327 = car::recode(sjlabelled::as_numeric(CC327), "1=-2;2=-1;3=1;4=2;else=NA"), | |
| CC332E = car::recode(sjlabelled::as_numeric(CC332E), "1=1;2=-1;else=NA"), | |
| CC332J = car::recode(sjlabelled::as_numeric(CC332J), "1=-1;2=1;else=NA"), | |
| CC414_2 = car::recode(sjlabelled::as_numeric(CC414_2), "1=1;2=-1;else=NA"), | |
| CC414_3 = car::recode(sjlabelled::as_numeric(CC414_3), "1=1;2=-1;else=NA"), | |
| CC414_4 = car::recode(sjlabelled::as_numeric(CC414_4), "1=-1;2=1;else=NA"), | |
| CC422a = car::recode(sjlabelled::as_numeric(CC422a), "1=-2;2=-1;3=0;4=1;5=2;else=NA"), | |
| CC422b = car::recode(sjlabelled::as_numeric(CC422b), "1=-2;2=-1;3=0;4=1;5=2;else=NA"), | |
| #econ | |
| CC325 = car::recode(sjlabelled::as_numeric(CC325), "1=-2;2=-1;3=0;4=1;5=2;else=NA"), | |
| CC328 = car::recode(sjlabelled::as_numeric(CC328), "1=-1;2=1;3=-1;else=NA"), | |
| CC332A = car::recode(sjlabelled::as_numeric(CC332A), "1=1;2=-1;else=NA"), | |
| CC332B = car::recode(sjlabelled::as_numeric(CC332B), "1=1;2=-1;else=NA"), | |
| CC332C = car::recode(sjlabelled::as_numeric(CC332C), "1=-1;2=1;else=NA"), | |
| CC332D = car::recode(sjlabelled::as_numeric(CC332D), "1=1;2=-1;else=NA"), | |
| CC332F = car::recode(sjlabelled::as_numeric(CC332F), "1=1;2=-1;else=NA"), | |
| CC332G = car::recode(sjlabelled::as_numeric(CC332G), "1=1;2=-1;else=NA"), | |
| CC332H = car::recode(sjlabelled::as_numeric(CC332H), "1=1;2=-1;else=NA"), | |
| CC332I = car::recode(sjlabelled::as_numeric(CC332I), "1=-1;2=1;else=NA"), | |
| CC414_2 = car::recode(sjlabelled::as_numeric(CC414_2), "1=1;2=-1;3=0;else=NA"), | |
| CC414_2 = car::recode(sjlabelled::as_numeric(CC414_2), "1=1;2=-1;3=0;else=NA"), | |
| CC414_3 = car::recode(sjlabelled::as_numeric(CC414_3), "1=-2;2=-1;3=1;4=2;else=NA") | |
| ) |> | |
| # Step 3: impute data at mean and standardize | |
| mutate(across(all_of(features), as.numeric)) |> | |
| mutate(across(all_of(features),\(x) tidyr::replace_na(x, mean(x, na.rm = TRUE)))) |> | |
| mutate(across(all_of(features), \(x) (x / max(x, na.rm = TRUE)))) | |
| data$social <- data |> | |
| select(all_of(social)) |> | |
| rowMeans(na.rm = TRUE) | |
| data$social <- (data$social - mean(data$social, na.rm = TRUE)) / sd(data$social, na.rm = TRUE) | |
| data$econ <- data |> | |
| select(all_of(econ)) |> | |
| rowMeans(na.rm = TRUE) | |
| data$econ <- (data$econ - mean(data$econ, na.rm = TRUE)) / sd(data$econ, na.rm = TRUE) | |
| data$race <- sjlabelled::as_labelled(data$race) | |
| data$pew_bornagain <- sjlabelled::as_labelled(data$pew_bornagain) | |
| data$religpew <- sjlabelled::as_labelled(data$religpew) | |
| data$religion_rc <- dplyr::case_when( | |
| data$religpew == 1 & data$race == 2 ~ "Black Protestant", | |
| data$religpew == 1 & data$pew_bornagain == 1 ~ "Evangelical", | |
| data$religpew == 1 & data$pew_bornagain != 1 ~ "Mainline", | |
| data$religpew == 2 ~ "Catholic", | |
| data$religpew == 3 ~ "Mormon", | |
| data$religpew == 4 ~ "Orthodox", | |
| data$religpew == 5 ~ "Jewish", | |
| data$religpew == 6 ~ "Muslim", | |
| data$religpew == 7 ~ "Buddhist", | |
| data$religpew == 8 ~ "Hindu", | |
| data$religpew == 9 ~ "Atheist", | |
| data$religpew == 10 ~ "Agnostic", | |
| data$religpew == 11 ~ "Nothing in particular", | |
| TRUE ~ NA_character_ | |
| ) | |
| data$cluster <- dplyr::case_when( | |
| data$pew_prayer == "Several times a day" & data$pew_religimp == "Very important" & data$pew_churatd %in% c("Once a week", "More than once a week") ~ "Devout Traditionalist", | |
| data$pew_churatd %in% c("Once a week", "More than once a week", "Once or twice a month") ~ "Adaptive Believer", | |
| TRUE ~ "Cultural Mormon" | |
| ) | |
| plot <- data |> | |
| ggplot() + | |
| geom_jitter(aes(x = econ, y = social),alpha = 0.05, width = 0.3, height = 0.3) + | |
| geom_point(data = data |> | |
| group_by(religion_rc) |> | |
| summarise( | |
| mean_econ = weighted.mean(econ, na.rm = TRUE, w = V103), | |
| mean_soc = weighted.mean(social, na.rm = TRUE, w = V103), | |
| n = n() | |
| ) |> | |
| drop_na(), aes(x = mean_econ, y = mean_soc, size = n, color = religion_rc), alpha = 0.7) + | |
| geom_text_repel( | |
| data = data |> | |
| group_by(religion_rc) |> | |
| summarise( | |
| mean_econ = weighted.mean(econ, na.rm = TRUE, w = V103), | |
| mean_soc = weighted.mean(social, na.rm = TRUE, w = V103), | |
| n = n() | |
| ) |> | |
| drop_na(), aes(x = mean_econ, y = mean_soc, label = religion_rc, color = religion_rc), size = 2.5, max.overlaps = Inf, fontface = "bold") + | |
| xlim(-3,3) + | |
| ylim(-3,3) + | |
| theme( | |
| axis.ticks = element_blank(), | |
| axis.title = element_text(size = 14), | |
| axis.text.y = element_text(size = 10), | |
| axis.text.x = element_text(size = 10, margin = margin(t = -5)), | |
| plot.background = element_rect(fill = "grey95"), # Change entire plot background color here | |
| panel.background = element_blank(), | |
| text = element_text(face = "bold", family = "Cairo"), | |
| plot.title = element_text(size = 15, face = "bold"), | |
| plot.subtitle = element_text(size = 11), | |
| plot.title.position = "plot", | |
| plot.subtitle.position = "plot", | |
| legend.title = element_blank(), | |
| legend.background = element_blank(), | |
| legend.box.background = element_blank(), | |
| legend.key = element_blank(), | |
| legend.text = element_text(size = 5), | |
| panel.grid = element_blank(), | |
| legend.position = "none", | |
| panel.grid.major.y = element_line(color = "lightgrey", linetype = 'solid'), | |
| panel.grid.major.x = element_line(color = "lightgrey", linetype = 'solid'), | |
| plot.caption = element_text(size = 8,family = "Cairo") | |
| )+ | |
| guides(size = "none") + | |
| labs( | |
| title = "2012 Political Compass by Religion", | |
| subtitle = "Comprehensive Variable Set (n = 28 Policy Questions)", | |
| x = "Economic (Left - Right)", | |
| y = "Social (Libertarian - Authoritarian)", | |
| caption = "@mormon_metrics\nData: 2012 Cooperative Election Study (n=54,535)" | |
| ) | |
| ggsave("./images/26_political_compass_2012.png", plot, width = 1500, height = 1500, units = "px", dpi = 300) | |
| data |> | |
| filter(religion_rc == "Mormon") |> | |
| nrow() | |
| plot <- data |> | |
| filter(religion_rc == "Mormon") |> | |
| ggplot() + | |
| geom_jitter(aes(x = econ, y = social),alpha = 0.05, width = 0.3, height = 0.3) + | |
| geom_point(data = data |> | |
| filter(religion_rc == "Mormon") |> | |
| group_by(cluster) |> | |
| summarise( | |
| mean_econ = weighted.mean(econ, na.rm = TRUE, w = V103), | |
| mean_soc = weighted.mean(social, na.rm = TRUE, w = V103), | |
| n = n() | |
| ) |> | |
| drop_na(), aes(x = mean_econ, y = mean_soc, size = n, color = cluster), alpha = 0.7) + | |
| geom_text_repel( | |
| data = data |> | |
| filter(religion_rc == "Mormon") |> | |
| group_by(cluster) |> | |
| summarise( | |
| mean_econ = weighted.mean(econ, na.rm = TRUE, w = V103), | |
| mean_soc = weighted.mean(social, na.rm = TRUE, w = V103), | |
| n = n() | |
| ) |> | |
| drop_na(), aes(x = mean_econ, y = mean_soc, label = cluster, color = cluster), size = 2.5, max.overlaps = Inf, fontface = "bold") + | |
| xlim(-3,3) + | |
| ylim(-3,3) + | |
| scale_size_area(max_size = 8) + | |
| theme( | |
| axis.ticks = element_blank(), | |
| axis.title = element_text(size = 14), | |
| axis.text.y = element_text(size = 10), | |
| axis.text.x = element_text(size = 10, margin = margin(t = -5)), | |
| plot.background = element_rect(fill = "grey95"), # Change entire plot background color here | |
| panel.background = element_blank(), | |
| text = element_text(face = "bold", family = "Cairo"), | |
| plot.title = element_text(size = 15, face = "bold"), | |
| plot.subtitle = element_text(size = 11), | |
| plot.title.position = "plot", | |
| plot.subtitle.position = "plot", | |
| legend.title = element_blank(), | |
| legend.background = element_blank(), | |
| legend.box.background = element_blank(), | |
| legend.key = element_blank(), | |
| legend.text = element_text(size = 5), | |
| panel.grid = element_blank(), | |
| legend.position = "none", | |
| panel.grid.major.y = element_line(color = "lightgrey", linetype = 'solid'), | |
| panel.grid.major.x = element_line(color = "lightgrey", linetype = 'solid'), | |
| plot.caption = element_text(size = 8,family = "Cairo") | |
| )+ | |
| guides(size = "none") + | |
| labs( | |
| title = "2012 Political Compass by LDS Cluster", | |
| subtitle = "Comprehensive Variable Set (n = 28 Policy Questions)", | |
| x = "Economic (Left - Right)", | |
| y = "Social (Libertarian - Authoritarian)", | |
| caption = "@mormon_metrics\nData: 2012 Cooperative Election Study (n=906 LDS)" | |
| ) | |
| ggsave("./images/26_political_compass_2012_mormon.png", plot, width = 1500, height = 1500, units = "px", dpi = 300) | |
| # 2016 | |
| # Load data | |
| # Ensure the file path matches where you saved the 2016 data | |
| data <- load('./data/CES/data/2016.RData') | |
| data <- x | |
| # --- 1. Define Variable Lists --- | |
| # SOCIAL VARIABLES | |
| # (Abortion, Guns, Immigration, Policing, Foreign Policy) | |
| social <- c( | |
| # Abortion | |
| 'CC16_332a', # Choice (Left) | |
| 'CC16_332b', # Rape/Incest Exceptions (Right) | |
| 'CC16_332c', # 20-Week Ban (Right) | |
| 'CC16_332d', # Insurance Opt-Out (Right) | |
| 'CC16_332e', # Federal Funding Ban (Right) | |
| 'CC16_332f', # Total Ban (Right) | |
| # LGBT | |
| 'CC16_335', # Gay Marriage (Left) | |
| # Guns | |
| 'CC16_330a', # Background Checks (Left) | |
| 'CC16_330b', # Publish Owners (Left) | |
| 'CC16_330d', # Ban Assault Rifles (Left) | |
| 'CC16_330e', # Concealed Carry (Right) | |
| # Immigration | |
| 'CC16_331_1', # Amnesty (Left) | |
| 'CC16_331_2', # Border Patrol (Right) | |
| 'CC16_331_3', # Dreamers (Left) | |
| 'CC16_331_7', # Deportation (Right) | |
| 'CC16_331_8', # Muslim Ban (Right) | |
| # Crime & Policing | |
| 'CC16_334a', # Eliminate Mandatory Mins (Left) | |
| 'CC16_334b', # Body Cameras (Left) | |
| 'CC16_334c', # Increase Police (Right) | |
| 'CC16_334d', # Increase Sentencing (Right) | |
| 'CC16_426_4', # State Spending: Law Enforcement (Right) | |
| # Foreign Policy / Troops | |
| 'CC16_351C', # USA Freedom Act/Surveillance (Left/Libertarian) | |
| 'CC16_351G', # Iran Sanctions (Right) | |
| 'CC16_414_1', # Troops: Oil (Right) | |
| 'CC16_414_2', # Troops: Terrorist Camp (Right) | |
| 'CC16_414_3', # Troops: Genocide (Left) | |
| 'CC16_414_4', # Troops: Democracy (Right - Neocon) | |
| 'CC16_414_5', # Troops: Protect Allies (Right) | |
| 'CC16_414_6' # Troops: UN / Int'l Law (Left) | |
| ) | |
| # ECONOMIC VARIABLES | |
| # (Taxes, Spending, Environment, Regulation) | |
| econ <- c( | |
| 'CC16_351I', # Repeal ACA (Right) | |
| 'CC16_351K', # Min Wage $12 (Left) | |
| 'CC16_351B', # TPP Trade Deal (Right/Globalist) | |
| 'CC16_351D', # Trade Adjustment Assistance (Left) | |
| 'CC16_351F', # Transport Funding (Left) | |
| 'CC16_351H', # Medicare Reform (Right) | |
| # Environment | |
| 'CC16_333a', # EPA CO2 Regulation (Left) | |
| 'CC16_333b', # Fuel Efficiency Standards (Left) | |
| 'CC16_333c', # Renewable Mandate (Left) | |
| 'CC16_333d', # Clean Air Act vs Jobs (Left) | |
| # State Spending | |
| 'CC16_426_1', # Welfare (Left) | |
| 'CC16_426_2', # Healthcare (Left) | |
| 'CC16_426_3', # Education (Left) | |
| 'CC16_426_5' # Transportation (Left) | |
| ) | |
| features <- c(econ, social) | |
| # --- 2. Recode Data --- | |
| # Logic: Right/Conservative = 1, Left/Liberal = -1 | |
| data <- data |> | |
| mutate( | |
| # --- SOCIAL RECODING --- | |
| # Abortion (1=Support, 2=Oppose) | |
| CC16_332a = car::recode(sjlabelled::as_numeric(CC16_332a), "1=-1; 2=1; else=NA"), # Choice -> Left | |
| CC16_332b = car::recode(sjlabelled::as_numeric(CC16_332b), "1=1; 2=-1; else=NA"), # Restrictions -> Right | |
| CC16_332c = car::recode(sjlabelled::as_numeric(CC16_332c), "1=1; 2=-1; else=NA"), # 20wk Ban -> Right | |
| CC16_332d = car::recode(sjlabelled::as_numeric(CC16_332d), "1=1; 2=-1; else=NA"), # Ins Opt-out -> Right | |
| CC16_332e = car::recode(sjlabelled::as_numeric(CC16_332e), "1=1; 2=-1; else=NA"), # Funding Ban -> Right | |
| CC16_332f = car::recode(sjlabelled::as_numeric(CC16_332f), "1=1; 2=-1; else=NA"), # Total Ban -> Right | |
| # Gay Marriage (1=Support, 2=Oppose) | |
| CC16_335 = car::recode(sjlabelled::as_numeric(CC16_335), "1=-1; 2=1; else=NA"), | |
| # Guns (1=Support, 2=Oppose) | |
| CC16_330a = car::recode(sjlabelled::as_numeric(CC16_330a), "1=-1; 2=1; else=NA"), # Background Checks -> Left | |
| CC16_330b = car::recode(sjlabelled::as_numeric(CC16_330b), "1=-1; 2=1; else=NA"), # Publish Owners -> Left | |
| CC16_330d = car::recode(sjlabelled::as_numeric(CC16_330d), "1=-1; 2=1; else=NA"), # Ban Assault -> Left | |
| CC16_330e = car::recode(sjlabelled::as_numeric(CC16_330e), "1=1; 2=-1; else=NA"), # Concealed Carry -> Right | |
| # Immigration (1=Support, 2=Oppose) | |
| CC16_331_1 = car::recode(sjlabelled::as_numeric(CC16_331_1), "1=-1; 2=1; else=NA"), # Amnesty -> Left | |
| CC16_331_2 = car::recode(sjlabelled::as_numeric(CC16_331_2), "1=1; 2=-1; else=NA"), # Border Patrol -> Right | |
| CC16_331_3 = car::recode(sjlabelled::as_numeric(CC16_331_3), "1=-1; 2=1; else=NA"), # Dreamers -> Left | |
| CC16_331_7 = car::recode(sjlabelled::as_numeric(CC16_331_7), "1=1; 2=-1; else=NA"), # Deportation -> Right | |
| CC16_331_8 = car::recode(sjlabelled::as_numeric(CC16_331_8), "1=1; 2=-1; else=NA"), # Muslim Ban -> Right | |
| # Crime (1=Support, 2=Oppose) | |
| CC16_334a = car::recode(sjlabelled::as_numeric(CC16_334a), "1=-1; 2=1; else=NA"), # End Mand Min -> Left | |
| CC16_334b = car::recode(sjlabelled::as_numeric(CC16_334b), "1=-1; 2=1; else=NA"), # Body Cams -> Left | |
| CC16_334c = car::recode(sjlabelled::as_numeric(CC16_334c), "1=1; 2=-1; else=NA"), # More Police -> Right | |
| CC16_334d = car::recode(sjlabelled::as_numeric(CC16_334d), "1=1; 2=-1; else=NA"), # Sentencing -> Right | |
| # Foreign Policy (1=Support, 2=Oppose) | |
| CC16_351G = car::recode(sjlabelled::as_numeric(CC16_351G), "1=1; 2=-1; else=NA"), # Iran Sanctions -> Right | |
| # Troops (1=Yes, 2=No) | |
| CC16_414_1 = car::recode(sjlabelled::as_numeric(CC16_414_1), "1=1; 2=-1; else=NA"), # Oil -> Right | |
| CC16_414_2 = car::recode(sjlabelled::as_numeric(CC16_414_2), "1=1; 2=-1; else=NA"), # Terrorists -> Right | |
| CC16_414_3 = car::recode(sjlabelled::as_numeric(CC16_414_3), "1=-1; 2=1; else=NA"), # Genocide -> Left | |
| CC16_414_4 = car::recode(sjlabelled::as_numeric(CC16_414_4), "1=1; 2=-1; else=NA"), # Democracy -> Right | |
| CC16_414_5 = car::recode(sjlabelled::as_numeric(CC16_414_5), "1=1; 2=-1; else=NA"), # Allies -> Right | |
| CC16_414_6 = car::recode(sjlabelled::as_numeric(CC16_414_6), "1=-1; 2=1; else=NA"), # UN -> Left | |
| # --- ECONOMIC RECODING --- | |
| # ACA & Medicare (1=Support, 2=Oppose) | |
| CC16_351I = car::recode(sjlabelled::as_numeric(CC16_351I), "1=1; 2=-1; else=NA"), # Repeal ACA -> Right | |
| CC16_351H = car::recode(sjlabelled::as_numeric(CC16_351H), "1=1; 2=-1; else=NA"), # Medicare Reform -> Right | |
| # Min Wage & Spending (1=Support, 2=Oppose) | |
| CC16_351K = car::recode(sjlabelled::as_numeric(CC16_351K), "1=-1; 2=1; else=NA"), # Min Wage -> Left | |
| CC16_351F = car::recode(sjlabelled::as_numeric(CC16_351F), "1=-1; 2=1; else=NA"), # Transp Funds -> Left | |
| CC16_351D = car::recode(sjlabelled::as_numeric(CC16_351D), "1=-1; 2=1; else=NA"), # Trade Aid -> Left | |
| # Trade (1=Support, 2=Oppose) | |
| CC16_351B = car::recode(sjlabelled::as_numeric(CC16_351B), "1=1; 2=-1; else=NA"), # TPP -> Right (Fiscal Conservative) | |
| # Environment (1=Support, 2=Oppose) | |
| CC16_333a = car::recode(sjlabelled::as_numeric(CC16_333a), "1=-1; 2=1; else=NA"), # EPA CO2 -> Left | |
| CC16_333b = car::recode(sjlabelled::as_numeric(CC16_333b), "1=-1; 2=1; else=NA"), # Fuel Eff -> Left | |
| CC16_333c = car::recode(sjlabelled::as_numeric(CC16_333c), "1=-1; 2=1; else=NA"), # Renewables -> Left | |
| # Clean Air Act (1=Enforce/Left, 2=Jobs/Right) | |
| CC16_333d = car::recode(sjlabelled::as_numeric(CC16_333d), "1=-1; 2=1; else=NA"), | |
| # State Spending (1=Increase, 2=Same, 3=Decrease) | |
| # Increase = -1 (Left) | Decrease = 1 (Right) | |
| CC16_426_1 = car::recode(sjlabelled::as_numeric(CC16_426_1), "1=-2; 2=-1; 3=0; 4=1; 5=2; else=NA"), # Welfare -> Left | |
| CC16_426_2 = car::recode(sjlabelled::as_numeric(CC16_426_2), "1=-2; 2=-1; 3=0; 4=1; 5=2; else=NA"), # Health -> Left | |
| CC16_426_3 = car::recode(sjlabelled::as_numeric(CC16_426_3), "1=-2; 2=-1; 3=0; 4=1; 5=2; else=NA"), # Education -> Left | |
| CC16_426_5 = car::recode(sjlabelled::as_numeric(CC16_426_5), "1=-2; 2=-1; 3=0; 4=1; 5=2; else=NA"), # Transport -> Left | |
| # Police Spending works opposite (Increase = Right) | |
| CC16_426_4 = car::recode(sjlabelled::as_numeric(CC16_426_4), "1=2; 2=1; 3=0; 4=-1; 5=-2; else=NA") # Police -> Right | |
| ) |> | |
| # --- 3. Impute & Standardize --- | |
| mutate(across(all_of(features), as.numeric)) |> | |
| mutate(across(all_of(features), \(x) tidyr::replace_na(x, mean(x, na.rm = TRUE)))) |> | |
| mutate(across(all_of(features), \(x) (x / max(abs(x), na.rm = TRUE)))) | |
| # --- 4. Calculate Scores --- | |
| # Calculate Means | |
| data$social <- data |> | |
| select(all_of(social)) |> | |
| rowMeans(na.rm = TRUE) | |
| data$econ <- data |> | |
| select(all_of(econ)) |> | |
| rowMeans(na.rm = TRUE) | |
| # Normalize Z-Scores | |
| data$social <- (data$social - mean(data$social, na.rm = TRUE)) / sd(data$social, na.rm = TRUE) | |
| data$econ <- (data$econ - mean(data$econ, na.rm = TRUE)) / sd(data$econ, na.rm = TRUE) | |
| # --- 5. Demographics & Labels --- | |
| data$race <- sjlabelled::as_labelled(data$race) | |
| data$pew_bornagain <- sjlabelled::as_labelled(data$pew_bornagain) | |
| data$religpew <- sjlabelled::as_labelled(data$religpew) | |
| data <- data |> | |
| mutate(religion_rc = dplyr::case_when( | |
| religpew == 1 & race == 2 ~ "Black Protestant", | |
| religpew == 1 & pew_bornagain == 1 ~ "Evangelical", | |
| religpew == 1 & pew_bornagain != 1 ~ "Mainline", | |
| religpew == 2 ~ "Catholic", | |
| religpew == 3 ~ "Mormon", | |
| religpew == 4 ~ "Orthodox", | |
| religpew == 5 ~ "Jewish", | |
| religpew == 6 ~ "Muslim", | |
| religpew == 7 ~ "Buddhist", | |
| religpew == 8 ~ "Hindu", | |
| religpew == 9 ~ "Atheist", | |
| religpew == 10 ~ "Agnostic", | |
| religpew == 11 ~ "Nothing in particular", | |
| TRUE ~ NA_character_ | |
| )) | |
| data$cluster <- dplyr::case_when( | |
| data$pew_prayer == "Several times a day" & data$pew_religimp == "Very important" & data$pew_churatd %in% c("Once a week", "More than once a week") ~ "Devout Traditionalist", | |
| data$pew_churatd %in% c("Once a week", "More than once a week", "Once or twice a month") ~ "Adaptive Believer", | |
| TRUE ~ "Cultural Mormon" | |
| ) | |
| # --- 6. Plotting --- | |
| plot <- data |> | |
| ggplot() + | |
| geom_jitter(aes(x = econ, y = social), alpha = 0.05, width = 0.3, height = 0.3) + | |
| # Weighted Means (Using 'commonweight' for 2016) | |
| geom_point(data = data |> | |
| group_by(religion_rc) |> | |
| summarise( | |
| mean_econ = weighted.mean(econ, na.rm = TRUE, w = commonweight), | |
| mean_soc = weighted.mean(social, na.rm = TRUE, w = commonweight), | |
| n = n() | |
| ) |> | |
| drop_na(), aes(x = mean_econ, y = mean_soc, size = n, color = religion_rc), alpha = 0.7) + | |
| geom_text_repel( | |
| data = data |> | |
| group_by(religion_rc) |> | |
| summarise( | |
| mean_econ = weighted.mean(econ, na.rm = TRUE, w = commonweight), | |
| mean_soc = weighted.mean(social, na.rm = TRUE, w = commonweight), | |
| n = n() | |
| ) |> | |
| drop_na(), aes(x = mean_econ, y = mean_soc, label = religion_rc, color = religion_rc), | |
| size = 2.5, max.overlaps = Inf, fontface = "bold") + | |
| xlim(-3, 3) + | |
| ylim(-3, 3) + | |
| theme( | |
| axis.ticks = element_blank(), | |
| axis.title = element_text(size = 14), | |
| axis.text.y = element_text(size = 10), | |
| axis.text.x = element_text(size = 10, margin = margin(t = -5)), | |
| plot.background = element_rect(fill = "grey95"), | |
| panel.background = element_blank(), | |
| text = element_text(face = "bold", family = "Cairo"), | |
| plot.title = element_text(size = 15, face = "bold"), | |
| plot.title.position = "plot", | |
| plot.subtitle.position = "plot", | |
| plot.subtitle = element_text(size = 11), | |
| legend.position = "none", | |
| panel.grid = element_blank(), | |
| panel.grid.major.y = element_line(color = "lightgrey", linetype = 'solid'), | |
| panel.grid.major.x = element_line(color = "lightgrey", linetype = 'solid'), | |
| plot.caption = element_text(size = 8, family = "Cairo") | |
| ) + | |
| labs( | |
| title = "2016 Political Compass by Religion", | |
| subtitle = "Comprehensive Variable Set (n = 43 Policy Questions)", | |
| x = "Economic (Left - Right)", | |
| y = "Social (Libertarian - Authoritarian)", | |
| caption = "@mormon_metrics\nData: 2016 Cooperative Election Study" | |
| ) | |
| ggsave("./images/26_political_compass_2016.png", plot, width = 1500, height = 1500, units = "px", dpi = 300) | |
| data |> | |
| filter(religion_rc == "Mormon") |> | |
| nrow() | |
| plot <- data |> | |
| filter(religion_rc == "Mormon") |> | |
| ggplot() + | |
| geom_jitter(aes(x = econ, y = social),alpha = 0.05, width = 0.3, height = 0.3) + | |
| geom_point(data = data |> | |
| filter(religion_rc == "Mormon") |> | |
| group_by(cluster) |> | |
| summarise( | |
| mean_econ = weighted.mean(econ, na.rm = TRUE, w = commonweight), | |
| mean_soc = weighted.mean(social, na.rm = TRUE, w = commonweight), | |
| n = n() | |
| ) |> | |
| drop_na(), aes(x = mean_econ, y = mean_soc, size = n, color = cluster), alpha = 0.7) + | |
| geom_text_repel( | |
| data = data |> | |
| filter(religion_rc == "Mormon") |> | |
| group_by(cluster) |> | |
| summarise( | |
| mean_econ = weighted.mean(econ, na.rm = TRUE, w = commonweight), | |
| mean_soc = weighted.mean(social, na.rm = TRUE, w = commonweight), | |
| n = n() | |
| ) |> | |
| drop_na(), aes(x = mean_econ, y = mean_soc, label = cluster, color = cluster), size = 2.5, max.overlaps = Inf, fontface = "bold") + | |
| xlim(-3,3) + | |
| ylim(-3,3) + | |
| scale_size_area(max_size = 8) + | |
| theme( | |
| axis.ticks = element_blank(), | |
| axis.title = element_text(size = 14), | |
| axis.text.y = element_text(size = 10), | |
| axis.text.x = element_text(size = 10, margin = margin(t = -5)), | |
| plot.background = element_rect(fill = "grey95"), # Change entire plot background color here | |
| panel.background = element_blank(), | |
| text = element_text(face = "bold", family = "Cairo"), | |
| plot.title = element_text(size = 15, face = "bold"), | |
| plot.subtitle = element_text(size = 11), | |
| plot.title.position = "plot", | |
| plot.subtitle.position = "plot", | |
| legend.title = element_blank(), | |
| legend.background = element_blank(), | |
| legend.box.background = element_blank(), | |
| legend.key = element_blank(), | |
| legend.text = element_text(size = 5), | |
| panel.grid = element_blank(), | |
| legend.position = "none", | |
| panel.grid.major.y = element_line(color = "lightgrey", linetype = 'solid'), | |
| panel.grid.major.x = element_line(color = "lightgrey", linetype = 'solid'), | |
| plot.caption = element_text(size = 8,family = "Cairo") | |
| )+ | |
| guides(size = "none") + | |
| labs( | |
| title = "2016 Political Compass by LDS Cluster", | |
| subtitle = "Comprehensive Variable Set (n = 43 Policy Questions)", | |
| x = "Economic (Left - Right)", | |
| y = "Social (Libertarian - Authoritarian)", | |
| caption = "@mormon_metrics\nData: 2016 Cooperative Election Study (n=870 LDS)" | |
| ) | |
| ggsave("./images/26_political_compass_2016_mormon.png", plot, width = 1500, height = 1500, units = "px", dpi = 300) | |
| # 2020 | |
| data <- haven::read_dta('./data/CES/data/2020.dta') | |
| # --- 1. Define Variable Lists --- | |
| # SOCIAL VARIABLES | |
| # (Abortion, Guns, Immigration, Policing, Courts, Civil Rights, Racial Resentment) | |
| social <- c( | |
| # Abortion | |
| 'CC20_332a', # Choice (Left) | |
| 'CC20_332b', # Exceptions Only (Right) | |
| 'CC20_332c', # 20-Week Ban (Right) | |
| 'CC20_332d', # Ins Opt-Out (Right) | |
| 'CC20_332e', # Fed Funding Ban (Right) | |
| 'CC20_332f', # Total Ban (Right) | |
| # Guns | |
| 'CC20_330a', # Privacy for Owners (Right) | |
| 'CC20_330b', # Ban Assault Rifles (Left) | |
| 'CC20_330c', # Concealed Carry (Right) | |
| # Immigration | |
| 'CC20_331a', # Amnesty (Left) | |
| 'CC20_331b', # Border Patrol (Right) | |
| 'CC20_331c', # Sanctuary Cities/Withhold Funds (Right) | |
| 'CC20_331d', # Reduce Legal Immigration (Right) | |
| 'CC20_331e', # Border Wall Spending (Right) | |
| 'CC20_350e', # Dreamers/DACA (Left) | |
| 'CC20_442c', # Emergency Declaration for Wall (Right) | |
| 'CC20_442d', # Remain in Mexico Policy (Right) | |
| # Policing & Criminal Justice (2020 Specific) | |
| 'CC20_334a', # End Mandatory Minimums (Left) | |
| 'CC20_334b', # Body Cameras (Left) | |
| 'CC20_334c', # Increase Police Funding (Right) | |
| 'CC20_334d', # Decrease Police Funding/Defund (Left) | |
| 'CC20_334e', # Ban Chokeholds (Left) | |
| 'CC20_334f', # Police Misconduct Registry (Left) | |
| 'CC20_334g', # End Military Gear Program (Left) | |
| 'CC20_334h', # End Qualified Immunity/Sue Police (Left) | |
| 'CC20_443_4', # State Spending: Law Enforcement (Right) | |
| # Civil Rights & Social Issues | |
| 'CC20_350a', # Equality Act (LGBTQ) (Left) | |
| 'CC20_355d', # Trans Military Ban (Right) | |
| 'CC20_440c', # Sexism: Women seek power over men (Right) | |
| 'CC20_440d', # Sexism: Women easily offended (Right) | |
| # Courts | |
| 'CC20_350c', # Confirm Kavanaugh (Right) | |
| 'CC20_356', # Confirm Amy Coney Barrett (Right) | |
| # Racial Resentment / Attitudes | |
| 'CC20_440a', # White Privilege Exists (Left) | |
| 'CC20_440b', # Racial Problems are Rare (Right) | |
| 'CC20_441a', # Irish/Italians worked up, Blacks should too (Right) | |
| 'CC20_441b', # Legacy of Slavery hinders Blacks (Left) | |
| 'CC20_441e' # Whites don't understand Black problems (Left) | |
| ) | |
| # ECONOMIC VARIABLES | |
| # (Healthcare, Taxes, Spending, Environment, Trade, COVID Stimulus) | |
| econ <- c( | |
| # Healthcare | |
| 'CC20_327a', # Medicare for All (Left) | |
| 'CC20_327b', # Negotiate Drug Prices (Left) | |
| 'CC20_327c', # Medicare Age 50 (Left) | |
| 'CC20_327d', # Repeal ACA (Right) | |
| 'CC20_327e', # Restore Individual Mandate (Left) | |
| # Wages & Labor | |
| 'CC20_350b', # Min Wage $15 (Left) | |
| 'CC20_350d', # Equal Pay Act (Left) | |
| 'CC20_355e', # SNAP Work Requirements (Right) | |
| # Environment | |
| 'CC20_333a', # EPA CO2 Regulation (Left) | |
| 'CC20_333b', # Renewable Mandate (Left) | |
| 'CC20_333c', # Clean Air Act vs Jobs (Left) | |
| 'CC20_333d', # Fuel Efficiency (Left) | |
| 'CC20_355a', # Withdraw Paris Agreement (Right) | |
| 'CC20_355c', # Repeal Clean Power Plan (Right) | |
| # Trade (Nationalist/Protectionist = Right in this era) | |
| 'CC20_338a', # China Tariffs (Right) | |
| 'CC20_338b', # Steel Tariffs (Right) | |
| 'CC20_355b', # Withdraw TPP (Right) | |
| # COVID Stimulus & Spending | |
| 'CC20_351a', # CARES Act $2T (Left/Spending) | |
| 'CC20_351b', # HEROES Act $3T (Left/Spending) | |
| 'CC20_443_1', # State Spending: Welfare (Left) | |
| 'CC20_443_2', # State Spending: Healthcare (Left) | |
| 'CC20_443_3', # State Spending: Education (Left) | |
| 'CC20_443_5' # State Spending: Infrastructure (Left) | |
| ) | |
| features <- c(econ, social) | |
| # --- 2. Recode Data --- | |
| # Logic: Right/Conservative = 1, Left/Liberal = -1 | |
| data <- data |> | |
| mutate( | |
| # --- SOCIAL RECODING --- | |
| # Abortion (1=Support, 2=Oppose) | |
| CC20_332a = car::recode(sjlabelled::as_numeric(CC20_332a), "1=-1; 2=1; else=NA"), # Choice -> Left | |
| CC20_332b = car::recode(sjlabelled::as_numeric(CC20_332b), "1=1; 2=-1; else=NA"), # Exceptions -> Right | |
| CC20_332c = car::recode(sjlabelled::as_numeric(CC20_332c), "1=1; 2=-1; else=NA"), # 20wk Ban -> Right | |
| CC20_332d = car::recode(sjlabelled::as_numeric(CC20_332d), "1=1; 2=-1; else=NA"), # Opt Out -> Right | |
| CC20_332e = car::recode(sjlabelled::as_numeric(CC20_332e), "1=1; 2=-1; else=NA"), # Funding Ban -> Right | |
| CC20_332f = car::recode(sjlabelled::as_numeric(CC20_332f), "1=1; 2=-1; else=NA"), # Total Ban -> Right | |
| # Guns (1=Support, 2=Oppose) | |
| CC20_330a = car::recode(sjlabelled::as_numeric(CC20_330a), "1=1; 2=-1; else=NA"), # Privacy -> Right | |
| CC20_330b = car::recode(sjlabelled::as_numeric(CC20_330b), "1=-1; 2=1; else=NA"), # Assault Ban -> Left | |
| CC20_330c = car::recode(sjlabelled::as_numeric(CC20_330c), "1=1; 2=-1; else=NA"), # Concealed -> Right | |
| # Immigration (1=Support, 2=Oppose) | |
| CC20_331a = car::recode(sjlabelled::as_numeric(CC20_331a), "1=-1; 2=1; else=NA"), # Amnesty -> Left | |
| CC20_331b = car::recode(sjlabelled::as_numeric(CC20_331b), "1=1; 2=-1; else=NA"), # Border Patrol -> Right | |
| CC20_331c = car::recode(sjlabelled::as_numeric(CC20_331c), "1=1; 2=-1; else=NA"), # Sanctuary/Funds -> Right | |
| CC20_331d = car::recode(sjlabelled::as_numeric(CC20_331d), "1=1; 2=-1; else=NA"), # Reduce Legal -> Right | |
| CC20_331e = car::recode(sjlabelled::as_numeric(CC20_331e), "1=1; 2=-1; else=NA"), # Border Wall -> Right | |
| CC20_350e = car::recode(sjlabelled::as_numeric(CC20_350e), "1=-1; 2=1; else=NA"), # Dreamers -> Left | |
| CC20_442c = car::recode(sjlabelled::as_numeric(CC20_442c), "1=1; 2=-1; else=NA"), # Emerg Wall -> Right | |
| CC20_442d = car::recode(sjlabelled::as_numeric(CC20_442d), "1=1; 2=-1; else=NA"), # Remain Mexico -> Right | |
| # Policing (1=Support, 2=Oppose) | |
| CC20_334a = car::recode(sjlabelled::as_numeric(CC20_334a), "1=-1; 2=1; else=NA"), # Mand Min -> Left | |
| CC20_334b = car::recode(sjlabelled::as_numeric(CC20_334b), "1=-1; 2=1; else=NA"), # Body Cams -> Left | |
| CC20_334c = car::recode(sjlabelled::as_numeric(CC20_334c), "1=1; 2=-1; else=NA"), # Increase Police -> Right | |
| CC20_334d = car::recode(sjlabelled::as_numeric(CC20_334d), "1=-1; 2=1; else=NA"), # Defund -> Left | |
| CC20_334e = car::recode(sjlabelled::as_numeric(CC20_334e), "1=-1; 2=1; else=NA"), # Chokeholds -> Left | |
| CC20_334f = car::recode(sjlabelled::as_numeric(CC20_334f), "1=-1; 2=1; else=NA"), # Registry -> Left | |
| CC20_334g = car::recode(sjlabelled::as_numeric(CC20_334g), "1=-1; 2=1; else=NA"), # End Mil Gear -> Left | |
| CC20_334h = car::recode(sjlabelled::as_numeric(CC20_334h), "1=-1; 2=1; else=NA"), # Sue Police -> Left | |
| # State Police Spending (1=Greatly Increase ... 5=Greatly Decrease) | |
| # Increase = Right | |
| CC20_443_4 = car::recode(sjlabelled::as_numeric(CC20_443_4), "1=2; 2=1; 3=0; 4=-1; 5=-2; else=NA"), | |
| # Civil Rights & Courts | |
| CC20_350a = car::recode(sjlabelled::as_numeric(CC20_350a), "1=-1; 2=1; else=NA"), # Equality Act -> Left | |
| CC20_350c = car::recode(sjlabelled::as_numeric(CC20_350c), "1=1; 2=-1; else=NA"), # Kavanaugh -> Right | |
| CC20_356 = car::recode(sjlabelled::as_numeric(CC20_356), "1=1; 2=-1; else=NA"), # Barrett -> Right | |
| CC20_355d = car::recode(sjlabelled::as_numeric(CC20_355d), "1=1; 2=-1; else=NA"), # Trans Ban -> Right | |
| # Racial Resentment / Sexism (1=Strongly Agree ... 5=Strongly Disagree) | |
| CC20_440a = car::recode(sjlabelled::as_numeric(CC20_440a), "1=-2; 2=-1; 3=0; 4=1; 5=2; else=NA"), # White Adv -> Left | |
| CC20_440b = car::recode(sjlabelled::as_numeric(CC20_440b), "1=2; 2=1; 3=0; 4=-1; 5=-2; else=NA"), # Rare Probs -> Right | |
| CC20_440c = car::recode(sjlabelled::as_numeric(CC20_440c), "1=2; 2=1; 3=0; 4=-1; 5=-2; else=NA"), # Women Power -> Right | |
| CC20_440d = car::recode(sjlabelled::as_numeric(CC20_440d), "1=2; 2=1; 3=0; 4=-1; 5=-2; else=NA"), # Women Offend -> Right | |
| CC20_441a = car::recode(sjlabelled::as_numeric(CC20_441a), "1=2; 2=1; 3=0; 4=-1; 5=-2; else=NA"), # Irish/Work Up -> Right | |
| CC20_441b = car::recode(sjlabelled::as_numeric(CC20_441b), "1=-2; 2=-1; 3=0; 4=1; 5=2; else=NA"), # Slavery -> Left | |
| CC20_441e = car::recode(sjlabelled::as_numeric(CC20_441e), "1=-2; 2=-1; 3=0; 4=1; 5=2; else=NA"), # Whites dont understand -> Left | |
| # --- ECONOMIC RECODING --- | |
| # Healthcare (1=Support, 2=Oppose) | |
| CC20_327a = car::recode(sjlabelled::as_numeric(CC20_327a), "1=-1; 2=1; else=NA"), # M4A -> Left | |
| CC20_327b = car::recode(sjlabelled::as_numeric(CC20_327b), "1=-1; 2=1; else=NA"), # Drug Prices -> Left | |
| CC20_327c = car::recode(sjlabelled::as_numeric(CC20_327c), "1=-1; 2=1; else=NA"), # Medicare 50 -> Left | |
| CC20_327d = car::recode(sjlabelled::as_numeric(CC20_327d), "1=1; 2=-1; else=NA"), # Repeal ACA -> Right | |
| CC20_327e = car::recode(sjlabelled::as_numeric(CC20_327e), "1=-1; 2=1; else=NA"), # Mandate -> Left | |
| # Wages (1=Support, 2=Oppose) | |
| CC20_350b = car::recode(sjlabelled::as_numeric(CC20_350b), "1=-1; 2=1; else=NA"), # Min Wage -> Left | |
| CC20_350d = car::recode(sjlabelled::as_numeric(CC20_350d), "1=-1; 2=1; else=NA"), # Equal Pay -> Left | |
| CC20_355e = car::recode(sjlabelled::as_numeric(CC20_355e), "1=1; 2=-1; else=NA"), # SNAP Work -> Right | |
| # Environment (1=Support, 2=Oppose) | |
| CC20_333a = car::recode(sjlabelled::as_numeric(CC20_333a), "1=-1; 2=1; else=NA"), # EPA CO2 -> Left | |
| CC20_333b = car::recode(sjlabelled::as_numeric(CC20_333b), "1=-1; 2=1; else=NA"), # Renewable -> Left | |
| CC20_333c = car::recode(sjlabelled::as_numeric(CC20_333c), "1=-1; 2=1; else=NA"), # Clean Air -> Left | |
| CC20_333d = car::recode(sjlabelled::as_numeric(CC20_333d), "1=-1; 2=1; else=NA"), # Fuel Eff -> Left | |
| CC20_355a = car::recode(sjlabelled::as_numeric(CC20_355a), "1=1; 2=-1; else=NA"), # Paris -> Right | |
| CC20_355c = car::recode(sjlabelled::as_numeric(CC20_355c), "1=1; 2=-1; else=NA"), # Repeal Clean Power -> Right | |
| # Trade (1=Support, 2=Oppose) | |
| CC20_338a = car::recode(sjlabelled::as_numeric(CC20_338a), "1=1; 2=-1; else=NA"), # China Tariffs -> Right | |
| CC20_338b = car::recode(sjlabelled::as_numeric(CC20_338b), "1=1; 2=-1; else=NA"), # Steel Tariffs -> Right | |
| CC20_355b = car::recode(sjlabelled::as_numeric(CC20_355b), "1=1; 2=-1; else=NA"), # Withdraw TPP -> Right | |
| # COVID Stimulus (1=Support, 2=Oppose) | |
| CC20_351a = car::recode(sjlabelled::as_numeric(CC20_351a), "1=-1; 2=1; else=NA"), # CARES -> Left | |
| CC20_351b = car::recode(sjlabelled::as_numeric(CC20_351b), "1=-1; 2=1; else=NA"), # HEROES -> Left | |
| # State Spending (1=Greatly Increase ... 5=Greatly Decrease) | |
| # Increase = Left (-), Decrease = Right (+) | |
| CC20_443_1 = car::recode(sjlabelled::as_numeric(CC20_443_1), "1=-2; 2=-1; 3=0; 4=1; 5=2; else=NA"), # Welfare -> Left | |
| CC20_443_2 = car::recode(sjlabelled::as_numeric(CC20_443_2), "1=-2; 2=-1; 3=0; 4=1; 5=2; else=NA"), # Health -> Left | |
| CC20_443_3 = car::recode(sjlabelled::as_numeric(CC20_443_3), "1=-2; 2=-1; 3=0; 4=1; 5=2; else=NA"), # Ed -> Left | |
| CC20_443_5 = car::recode(sjlabelled::as_numeric(CC20_443_5), "1=-2; 2=-1; 3=0; 4=1; 5=2; else=NA") # Infra -> Left | |
| ) |> | |
| # --- 3. Impute & Standardize --- | |
| mutate(across(all_of(features), as.numeric)) |> | |
| mutate(across(all_of(features), \(x) tidyr::replace_na(x, mean(x, na.rm = TRUE)))) |> | |
| mutate(across(all_of(features), \(x) (x / max(abs(x), na.rm = TRUE)))) | |
| # --- 4. Calculate Scores --- | |
| # Calculate Means | |
| data$social <- data |> | |
| select(all_of(social)) |> | |
| rowMeans(na.rm = TRUE) | |
| data$econ <- data |> | |
| select(all_of(econ)) |> | |
| rowMeans(na.rm = TRUE) | |
| # Normalize Z-Scores | |
| data$social <- (data$social - mean(data$social, na.rm = TRUE)) / sd(data$social, na.rm = TRUE) | |
| data$econ <- (data$econ - mean(data$econ, na.rm = TRUE)) / sd(data$econ, na.rm = TRUE) | |
| # --- 5. Demographics & Labels --- | |
| data$race <- sjlabelled::as_labelled(data$race) | |
| data$pew_bornagain <- sjlabelled::as_labelled(data$pew_bornagain) | |
| data$religpew <- sjlabelled::as_labelled(data$religpew) | |
| data <- data |> | |
| mutate(religion_rc = dplyr::case_when( | |
| religpew == 1 & race == 2 ~ "Black Protestant", | |
| religpew == 1 & pew_bornagain == 1 ~ "Evangelical", | |
| religpew == 1 & pew_bornagain != 1 ~ "Mainline", | |
| religpew == 2 ~ "Catholic", | |
| religpew == 3 ~ "Mormon", | |
| religpew == 4 ~ "Orthodox", | |
| religpew == 5 ~ "Jewish", | |
| religpew == 6 ~ "Muslim", | |
| religpew == 7 ~ "Buddhist", | |
| religpew == 8 ~ "Hindu", | |
| religpew == 9 ~ "Atheist", | |
| religpew == 10 ~ "Agnostic", | |
| religpew == 11 ~ "Nothing in particular", | |
| TRUE ~ NA_character_ | |
| )) | |
| # --- 6. Plotting --- | |
| plot <- data |> | |
| ggplot() + | |
| geom_jitter(aes(x = econ, y = social), alpha = 0.05, width = 0.3, height = 0.3) + | |
| # Weighted Means (Using 'commonweight' for 2020) | |
| geom_point(data = data |> | |
| group_by(religion_rc) |> | |
| summarise( | |
| mean_econ = weighted.mean(econ, na.rm = TRUE, w = commonweight), | |
| mean_soc = weighted.mean(social, na.rm = TRUE, w = commonweight), | |
| n = n() | |
| ) |> | |
| drop_na(), aes(x = mean_econ, y = mean_soc, size = n, color = religion_rc), alpha = 0.7) + | |
| geom_text_repel( | |
| data = data |> | |
| group_by(religion_rc) |> | |
| summarise( | |
| mean_econ = weighted.mean(econ, na.rm = TRUE, w = commonweight), | |
| mean_soc = weighted.mean(social, na.rm = TRUE, w = commonweight), | |
| n = n() | |
| ) |> | |
| drop_na(), aes(x = mean_econ, y = mean_soc, label = religion_rc, color = religion_rc), | |
| size = 2.5, max.overlaps = Inf, fontface = "bold") + | |
| xlim(-3, 3) + | |
| ylim(-3, 3) + | |
| theme( | |
| axis.ticks = element_blank(), | |
| axis.title = element_text(size = 14), | |
| axis.text.y = element_text(size = 10), | |
| axis.text.x = element_text(size = 10, margin = margin(t = -5)), | |
| plot.background = element_rect(fill = "grey95"), | |
| panel.background = element_blank(), | |
| text = element_text(face = "bold", family = "Cairo"), | |
| plot.title = element_text(size = 15, face = "bold"), | |
| plot.subtitle = element_text(size = 11), | |
| legend.position = "none", | |
| panel.grid = element_blank(), | |
| panel.grid.major.y = element_line(color = "lightgrey", linetype = 'solid'), | |
| panel.grid.major.x = element_line(color = "lightgrey", linetype = 'solid'), | |
| plot.caption = element_text(size = 8, family = "Cairo") | |
| ) + | |
| labs( | |
| title = "2020 Political Compass by Religion", | |
| subtitle = "Comprehensive Variable Set (n=60 Policy Questions)", | |
| x = "Economic (Left - Right)", | |
| y = "Social (Libertarian - Authoritarian)", | |
| caption = "@mormon_metrics\nData: 2020 Cooperative Election Study" | |
| ) | |
| ggsave("./images/26_political_compass_2020.png", plot, width = 1500, height = 1500, units = "px", dpi = 300) | |
| data |> | |
| filter(religion_rc == "Mormon") |> | |
| nrow() | |
| data$cluster <- dplyr::case_when( | |
| data$pew_prayer == 1 & data$pew_religimp == 1 & data$pew_churatd %in% 1:2 ~ "Devout Traditionalist", | |
| data$pew_churatd %in% 1:3 ~ "Adaptive Believer", | |
| TRUE ~ "Cultural Mormon" | |
| ) | |
| plot <- data |> | |
| filter(religion_rc == "Mormon") |> | |
| ggplot() + | |
| geom_jitter(aes(x = econ, y = social),alpha = 0.05, width = 0.3, height = 0.3) + | |
| geom_point(data = data |> | |
| filter(religion_rc == "Mormon") |> | |
| group_by(cluster) |> | |
| summarise( | |
| mean_econ = weighted.mean(econ, na.rm = TRUE, w = commonweight), | |
| mean_soc = weighted.mean(social, na.rm = TRUE, w = commonweight), | |
| n = n() | |
| ) |> | |
| drop_na(), aes(x = mean_econ, y = mean_soc, size = n, color = cluster), alpha = 0.7) + | |
| geom_text_repel( | |
| data = data |> | |
| filter(religion_rc == "Mormon") |> | |
| group_by(cluster) |> | |
| summarise( | |
| mean_econ = weighted.mean(econ, na.rm = TRUE, w = commonweight), | |
| mean_soc = weighted.mean(social, na.rm = TRUE, w = commonweight), | |
| n = n() | |
| ) |> | |
| drop_na(), aes(x = mean_econ, y = mean_soc, label = cluster, color = cluster), size = 2.5, max.overlaps = Inf, fontface = "bold") + | |
| xlim(-3,3) + | |
| ylim(-3,3) + | |
| scale_size_area(max_size = 8) + | |
| theme( | |
| axis.ticks = element_blank(), | |
| axis.title = element_text(size = 14), | |
| axis.text.y = element_text(size = 10), | |
| axis.text.x = element_text(size = 10, margin = margin(t = -5)), | |
| plot.background = element_rect(fill = "grey95"), # Change entire plot background color here | |
| panel.background = element_blank(), | |
| text = element_text(face = "bold", family = "Cairo"), | |
| plot.title = element_text(size = 15, face = "bold"), | |
| plot.subtitle = element_text(size = 11), | |
| plot.title.position = "plot", | |
| plot.subtitle.position = "plot", | |
| legend.title = element_blank(), | |
| legend.background = element_blank(), | |
| legend.box.background = element_blank(), | |
| legend.key = element_blank(), | |
| legend.text = element_text(size = 5), | |
| panel.grid = element_blank(), | |
| legend.position = "none", | |
| panel.grid.major.y = element_line(color = "lightgrey", linetype = 'solid'), | |
| panel.grid.major.x = element_line(color = "lightgrey", linetype = 'solid'), | |
| plot.caption = element_text(size = 8,family = "Cairo") | |
| )+ | |
| guides(size = "none") + | |
| labs( | |
| title = "2020 Political Compass by LDS Cluster", | |
| subtitle = "Comprehensive Variable Set (n=60 Policy Questions)", | |
| x = "Economic (Left - Right)", | |
| y = "Social (Libertarian - Authoritarian)", | |
| caption = "@mormon_metrics\nData: 2020 Cooperative Election Study (n=763 LDS)" | |
| ) | |
| ggsave("./images/26_political_compass_2020_mormon.png", plot, width = 1500, height = 1500, units = "px", dpi = 300) | |
| # 2024 | |
| data <- haven::read_dta('./data/CES/data/2024.dta', encoding = 'UTF-8') | |
| # Step 1: identify features | |
| social <- c( | |
| 'CC24_308a_1', | |
| 'CC24_308a_2', | |
| 'CC24_308a_3', | |
| 'CC24_308a_4', | |
| 'CC24_308a_6', | |
| 'CC24_308b_1', | |
| 'CC24_308b_2', | |
| 'CC24_308b_3', | |
| 'CC24_308b_5', | |
| 'CC24_321a', | |
| 'CC24_321b', | |
| 'CC24_321c', | |
| 'CC24_321d', | |
| 'CC24_321e', | |
| 'CC24_323a', | |
| 'CC24_323b', | |
| 'CC24_323c', | |
| 'CC24_323d', | |
| 'CC24_324a', | |
| 'CC24_324b', | |
| 'CC24_324c', | |
| 'CC24_324d', | |
| 'CC24_340a', | |
| 'CC24_340b', | |
| 'CC24_340c', | |
| 'CC24_340d', | |
| 'CC24_340e', | |
| 'CC24_340f', | |
| 'CC24_420_1', | |
| 'CC24_420_2', | |
| 'CC24_420_3', | |
| 'CC24_420_4', | |
| 'CC24_420_5', | |
| 'CC24_420_6', | |
| 'CC24_420_7', | |
| 'CC24_444a', | |
| 'CC24_444b', | |
| 'CC24_444c', | |
| 'CC24_444d', | |
| 'CC24_444e', | |
| 'CC24_445a', | |
| 'CC24_445b', | |
| 'CC24_440a', | |
| 'CC24_440b', | |
| 'CC24_440c', | |
| 'CC24_440d', | |
| 'CC24_441a', | |
| 'CC24_441b', | |
| 'CC24_441e' | |
| ) | |
| econ <- c( | |
| 'CC24_326a', | |
| 'CC24_326b', | |
| 'CC24_326c', | |
| 'CC24_326d', | |
| 'CC24_326e', | |
| 'CC24_326f', | |
| 'CC24_328a', | |
| 'CC24_328b', | |
| 'CC24_328c', | |
| 'CC24_328d', | |
| 'CC24_328e', | |
| 'CC24_443_1', | |
| 'CC24_443_2', | |
| 'CC24_443_3', | |
| 'CC24_443_4', | |
| 'CC24_443_5', | |
| 'CC24_444f' | |
| ) | |
| features <- c( | |
| econ, | |
| social | |
| ) | |
| data <- data |> | |
| # Step 2: recode features to all be in same direction | |
| mutate( | |
| id = paste0('2024X', caseid), | |
| CC24_308a_1 = car::recode(sjlabelled::as_numeric(CC24_308a_1), "1=-1; 2=1;else=NA"), | |
| CC24_308a_2 = car::recode(sjlabelled::as_numeric(CC24_308a_2), "1=-1; 2=1;else=NA"), | |
| CC24_308a_3 = car::recode(sjlabelled::as_numeric(CC24_308a_3), "1=1; 2=-1;else=NA"), | |
| CC24_308a_4 = car::recode(sjlabelled::as_numeric(CC24_308a_4), "1=1; 2=-1;else=NA"), | |
| CC24_308a_6 = car::recode(sjlabelled::as_numeric(CC24_308a_6), "1=1; 2=-1;else=NA"), | |
| CC24_308b_1 = car::recode(sjlabelled::as_numeric(CC24_308b_1), "1=-1; 2=1;else=NA"), | |
| CC24_308b_2 = car::recode(sjlabelled::as_numeric(CC24_308b_2), "1=-1; 2=1;else=NA"), | |
| CC24_308b_3 = car::recode(sjlabelled::as_numeric(CC24_308b_3), "1=1; 2=-1;else=NA"), | |
| CC24_308b_5 = car::recode(sjlabelled::as_numeric(CC24_308b_5), "1=1; 2=-1;else=NA"), | |
| CC24_321a = car::recode(sjlabelled::as_numeric(CC24_321a), "1=-1;2=1;else=NA"), | |
| CC24_321b = car::recode(sjlabelled::as_numeric(CC24_321b), "1=-1;2=1;else=NA"), | |
| CC24_321c = car::recode(sjlabelled::as_numeric(CC24_321c), "1=-1;2=1;else=NA"), | |
| CC24_321d = car::recode(sjlabelled::as_numeric(CC24_321d), "1=-1;2=1;else=NA"), | |
| CC24_321e = car::recode(sjlabelled::as_numeric(CC24_321e), "1=1;2=-1;else=NA"), | |
| CC24_323a = car::recode(sjlabelled::as_numeric(CC24_323a), "1=-1;2=1;3=0;else=NA"), | |
| CC24_323b = car::recode(sjlabelled::as_numeric(CC24_323b), "1=1;2=-1;3=0;else=NA"), | |
| CC24_323c = car::recode(sjlabelled::as_numeric(CC24_323c), "1=1;2=-1;3=0;else=NA"), | |
| CC24_323d = car::recode(sjlabelled::as_numeric(CC24_323d), "1=-1;2=1;3=0;else=NA"), | |
| CC24_324a = car::recode(sjlabelled::as_numeric(CC24_324a), "1=-1;2=1;3=0;else=NA"), | |
| CC24_324b = car::recode(sjlabelled::as_numeric(CC24_324b), "1=1;2=-1;3=0;else=NA"), | |
| CC24_324c = car::recode(sjlabelled::as_numeric(CC24_324c), "1=1;2=-1;3=0;else=NA"), | |
| CC24_324d = car::recode(sjlabelled::as_numeric(CC24_324d), "1=-1;2=1;3=0;else=NA"), | |
| CC24_340a = car::recode(sjlabelled::as_numeric(CC24_340a), "1=-1;2=1;else=NA"), | |
| CC24_340b = car::recode(sjlabelled::as_numeric(CC24_340b), "1=-1;2=1;3=0;else=NA"), | |
| CC24_340c = car::recode(sjlabelled::as_numeric(CC24_340c), "1=-1;2=1;3=0;else=NA"), | |
| CC24_340d = car::recode(sjlabelled::as_numeric(CC24_340d), "1=1;2=-1;3=0;else=NA"), | |
| CC24_340e = car::recode(sjlabelled::as_numeric(CC24_340e), "1=1;2=-1;3=0;else=NA"), | |
| CC24_340f = car::recode(sjlabelled::as_numeric(CC24_340f), "1=1;2=-1;3=0;else=NA"), | |
| CC24_420_1 = car::recode(sjlabelled::as_numeric(CC24_420_1), "1=1;2=-1;3=0;else=NA"), | |
| CC24_420_2 = car::recode(sjlabelled::as_numeric(CC24_420_2), "1=1;2=-1;3=0;else=NA"), | |
| CC24_420_3 = car::recode(sjlabelled::as_numeric(CC24_420_3), "1=1;2=-1;3=0;else=NA"), | |
| CC24_420_4 = car::recode(sjlabelled::as_numeric(CC24_420_4), "1=1;2=-1;3=0;else=NA"), | |
| CC24_420_5 = car::recode(sjlabelled::as_numeric(CC24_420_5), "1=-1;2=1;3=0;else=NA"), | |
| CC24_420_6 = car::recode(sjlabelled::as_numeric(CC24_420_6), "1=-1;2=1;3=0;else=NA"), | |
| CC24_420_7 = car::recode(sjlabelled::as_numeric(CC24_420_7), "1=-1;2=1;3=0;else=NA"), | |
| CC24_440a = car::recode(sjlabelled::as_numeric(CC24_440a), "1=-2;2=-1;3=0;4=1;5=2;else=NA"), | |
| CC24_440b = car::recode(sjlabelled::as_numeric(CC24_440b), "1=2;2=1;3=0;4=-1;5=-2;else=NA"), | |
| CC24_440c = car::recode(sjlabelled::as_numeric(CC24_440c), "1=2;2=1;3=0;4=-1;5=-2;else=NA"), | |
| CC24_440d = car::recode(sjlabelled::as_numeric(CC24_440d), "1=2;2=1;3=0;4=-1;5=-2;else=NA"), | |
| CC24_445a = car::recode(sjlabelled::as_numeric(CC24_444d), "1=1;2=-1;else=NA"), | |
| CC24_445b = car::recode(sjlabelled::as_numeric(CC24_445b), "1=1;2=-1;else=NA"), | |
| CC24_444a = car::recode(sjlabelled::as_numeric(CC24_444a), "1=1;2=-1;3=0;else=NA"), | |
| CC24_444b = car::recode(sjlabelled::as_numeric(CC24_444b), "1=1;2=-1;3=0;else=NA"), | |
| CC24_444c = car::recode(sjlabelled::as_numeric(CC24_444c), "1=1;2=-1;3=0;else=NA"), | |
| CC24_444d = car::recode(sjlabelled::as_numeric(CC24_444d), "1=1;2=-1;3=0;else=NA"), | |
| CC24_444e = car::recode(sjlabelled::as_numeric(CC24_444e), "1=1;2=-1;3=0;else=NA"), | |
| CC24_441a = car::recode(sjlabelled::as_numeric(CC24_441a), "1=2;2=1;3=0;4=-1;5=-2;else=NA"), | |
| CC24_441b = car::recode(sjlabelled::as_numeric(CC24_441b), "1=-2;2=-1;3=0;4=1;5=2;else=NA"), | |
| CC24_441e = car::recode(sjlabelled::as_numeric(CC24_441e), "1=-2;2=-1;3=0;4=1;5=2;else=NA"), | |
| CC24_326a = car::recode(sjlabelled::as_numeric(CC24_326a), "1=-1;2=1;else=NA"), | |
| CC24_326b = car::recode(sjlabelled::as_numeric(CC24_326b), "1=-1;2=1;else=NA"), | |
| CC24_326c = car::recode(sjlabelled::as_numeric(CC24_326c), "1=-1;2=1;else=NA"), | |
| CC24_326d = car::recode(sjlabelled::as_numeric(CC24_326d), "1=1;2=-1;else=NA"), | |
| CC24_326e = car::recode(sjlabelled::as_numeric(CC24_326e), "1=-1;2=1;else=NA"), | |
| CC24_326f = car::recode(sjlabelled::as_numeric(CC24_326f), "1=1;2=-1;else=NA"), | |
| CC24_328a = car::recode(sjlabelled::as_numeric(CC24_328a), "1=1;2=-1;else=NA"), | |
| CC24_328b = car::recode(sjlabelled::as_numeric(CC24_328b), "1=-1;2=1;else=NA"), | |
| CC24_328c = car::recode(sjlabelled::as_numeric(CC24_328c), "1=1;2=-1;else=NA"), | |
| CC24_328d = car::recode(sjlabelled::as_numeric(CC24_328d), "1=1;2=-1;else=NA"), | |
| CC24_328e = car::recode(sjlabelled::as_numeric(CC24_328e), "1=-1;2=1;else=NA"), | |
| CC24_443_1 = car::recode(sjlabelled::as_numeric(CC24_443_1), "1=-2;2=-1;3=0;4=1;5=2;else=NA"), | |
| CC24_443_2 = car::recode(sjlabelled::as_numeric(CC24_443_2), "1=-2;2=-1;3=0;4=1;5=2;else=NA"), | |
| CC24_443_3 = car::recode(sjlabelled::as_numeric(CC24_443_3), "1=-2;2=-1;3=0;4=1;5=2;else=NA"), | |
| CC24_443_4 = car::recode(sjlabelled::as_numeric(CC24_443_4), "1=-2;2=-1;3=0;4=1;5=2;else=NA"), | |
| CC24_443_5 = car::recode(sjlabelled::as_numeric(CC24_443_5), "1=-2;2=-1;3=0;4=1;5=2;else=NA"), | |
| CC24_444f = car::recode(sjlabelled::as_numeric(CC24_444f), "1=-1;2=1;else=NA") | |
| ) |> | |
| # Step 3: impute data at mean and standardize | |
| mutate(across(all_of(features), as.numeric)) |> | |
| mutate(across(all_of(features),\(x) tidyr::replace_na(x, mean(x, na.rm = TRUE)))) | |
| # # |> | |
| # mutate(across(all_of(features), \(x) (x - mean(x, na.rm = TRUE)) / sd(x, na.rm = TRUE))) | |
| # create a social and economic variable | |
| data$social <- data |> | |
| select(all_of(social)) |> | |
| rowMeans(na.rm = TRUE) | |
| data$social <- (data$social - mean(data$social, na.rm = TRUE)) / sd(data$social, na.rm = TRUE) | |
| data$econ <- data |> | |
| select(all_of(econ)) |> | |
| rowMeans(na.rm = TRUE) | |
| data$econ <- (data$econ - mean(data$econ, na.rm = TRUE)) / sd(data$econ, na.rm = TRUE) | |
| data$religion_rc <- dplyr::case_when( | |
| data$religpew == 1 & data$race == 2 ~ "Black Protestant", | |
| data$religpew == 1 & data$pew_bornagain == 1 ~ "Evangelical", | |
| data$religpew == 1 & data$pew_bornagain != 1 ~ "Mainline", | |
| data$religpew == 2 ~ "Catholic", | |
| data$religpew == 3 ~ "Mormon", | |
| data$religpew == 4 ~ "Orthodox", | |
| data$religpew == 5 ~ "Jewish", | |
| data$religpew == 6 ~ "Muslim", | |
| data$religpew == 7 ~ "Buddhist", | |
| data$religpew == 8 ~ "Hindu", | |
| data$religpew == 9 ~ "Atheist", | |
| data$religpew == 10 ~ "Agnostic", | |
| data$religpew == 11 ~ "Nothing in particular", | |
| TRUE ~ NA_character_ | |
| ) | |
| plot <- data |> | |
| ggplot() + | |
| geom_jitter(aes(x = econ, y = social),alpha = 0.05, width = 0.3, height = 0.3) + | |
| geom_point(data = data |> | |
| group_by(religion_rc) |> | |
| summarise( | |
| mean_econ = weighted.mean(econ, na.rm = TRUE, w = commonweight), | |
| mean_soc = weighted.mean(social, na.rm = TRUE, w = commonweight), | |
| n = n() | |
| ) |> | |
| drop_na(), aes(x = mean_econ, y = mean_soc, size = n, color = religion_rc), alpha = 0.7) + | |
| geom_text_repel( | |
| data = data |> | |
| group_by(religion_rc) |> | |
| summarise( | |
| mean_econ = weighted.mean(econ, na.rm = TRUE, w = commonweight), | |
| mean_soc = weighted.mean(social, na.rm = TRUE, w = commonweight), | |
| n = n() | |
| ) |> | |
| drop_na(), aes(x = mean_econ, y = mean_soc, label = religion_rc, color = religion_rc), size = 2.5, max.overlaps = Inf, fontface = "bold") + | |
| xlim(-3,3) + | |
| ylim(-3,3) + | |
| theme( | |
| axis.ticks = element_blank(), | |
| axis.title = element_text(size = 14), | |
| axis.text.y = element_text(size = 10), | |
| axis.text.x = element_text(size = 10, margin = margin(t = -5)), | |
| plot.background = element_rect(fill = "grey95"), # Change entire plot background color here | |
| panel.background = element_blank(), | |
| text = element_text(face = "bold", family = "Cairo"), | |
| plot.title = element_text(size = 15, face = "bold"), | |
| plot.subtitle = element_text(size = 11), | |
| plot.title.position = "plot", | |
| plot.subtitle.position = "plot", | |
| legend.title = element_blank(), | |
| legend.background = element_blank(), | |
| legend.box.background = element_blank(), | |
| legend.key = element_blank(), | |
| legend.text = element_text(size = 5), | |
| panel.grid = element_blank(), | |
| legend.position = "none", | |
| panel.grid.major.y = element_line(color = "lightgrey", linetype = 'solid'), | |
| panel.grid.major.x = element_line(color = "lightgrey", linetype = 'solid'), | |
| plot.caption = element_text(size = 8,family = "Cairo") | |
| )+ | |
| guides(size = "none") + | |
| labs( | |
| title = "2024 Political Compass by Religion", | |
| subtitle = "Comprehensive Variable Set (n = 66 Policy Questions)", | |
| x = "Economic (Left - Right)", | |
| y = "Social (Libertarian - Authoritarian)", | |
| caption = "@mormon_metrics\nData: 2024 Cooperative Election Study" | |
| ) | |
| ggsave("./images/26_political_compass_2024.png", plot, width = 1500, height = 1500, units = "px", dpi = 300) | |
| data |> | |
| filter(religion_rc == "Mormon") |> | |
| nrow() | |
| data$cluster <- dplyr::case_when( | |
| data$pew_prayer == 1 & data$pew_religimp == 1 & data$pew_churatd %in% 1:2 ~ "Devout Traditionalist", | |
| data$pew_churatd %in% 1:3 ~ "Adaptive Believer", | |
| TRUE ~ "Cultural Mormon" | |
| ) | |
| plot <- data |> | |
| filter(religion_rc == "Mormon") |> | |
| ggplot() + | |
| geom_jitter(aes(x = econ, y = social),alpha = 0.05, width = 0.3, height = 0.3) + | |
| geom_point(data = data |> | |
| filter(religion_rc == "Mormon") |> | |
| group_by(cluster) |> | |
| summarise( | |
| mean_econ = weighted.mean(econ, na.rm = TRUE, w = commonweight), | |
| mean_soc = weighted.mean(social, na.rm = TRUE, w = commonweight), | |
| n = n() | |
| ) |> | |
| drop_na(), aes(x = mean_econ, y = mean_soc, size = n, color = cluster), alpha = 0.7) + | |
| geom_text_repel( | |
| data = data |> | |
| filter(religion_rc == "Mormon") |> | |
| group_by(cluster) |> | |
| summarise( | |
| mean_econ = weighted.mean(econ, na.rm = TRUE, w = commonweight), | |
| mean_soc = weighted.mean(social, na.rm = TRUE, w = commonweight), | |
| n = n() | |
| ) |> | |
| drop_na(), aes(x = mean_econ, y = mean_soc, label = cluster, color = cluster), size = 2.5, max.overlaps = Inf, fontface = "bold") + | |
| xlim(-3,3) + | |
| ylim(-3,3) + | |
| scale_size_area(max_size = 8) + | |
| theme( | |
| axis.ticks = element_blank(), | |
| axis.title = element_text(size = 14), | |
| axis.text.y = element_text(size = 10), | |
| axis.text.x = element_text(size = 10, margin = margin(t = -5)), | |
| plot.background = element_rect(fill = "grey95"), # Change entire plot background color here | |
| panel.background = element_blank(), | |
| text = element_text(face = "bold", family = "Cairo"), | |
| plot.title = element_text(size = 15, face = "bold"), | |
| plot.subtitle = element_text(size = 11), | |
| plot.title.position = "plot", | |
| plot.subtitle.position = "plot", | |
| legend.title = element_blank(), | |
| legend.background = element_blank(), | |
| legend.box.background = element_blank(), | |
| legend.key = element_blank(), | |
| legend.text = element_text(size = 5), | |
| panel.grid = element_blank(), | |
| legend.position = "none", | |
| panel.grid.major.y = element_line(color = "lightgrey", linetype = 'solid'), | |
| panel.grid.major.x = element_line(color = "lightgrey", linetype = 'solid'), | |
| plot.caption = element_text(size = 8,family = "Cairo") | |
| )+ | |
| guides(size = "none") + | |
| labs( | |
| title = "2024 Political Compass by LDS Cluster", | |
| subtitle = "Comprehensive Variable Set (n = 66 Policy Questions)", | |
| x = "Economic (Left - Right)", | |
| y = "Social (Libertarian - Authoritarian)", | |
| caption = "@mormon_metrics\nData: 2024 Cooperative Election Study (n=623 LDS)" | |
| ) | |
| ggsave("./images/26_political_compass_2024_mormon.png", plot, width = 1500, height = 1500, units = "px", dpi = 300) | |
| data |> | |
| mutate(type = dplyr::case_when( | |
| econ < 0 & social < 0 ~ "Progressives", | |
| econ >= 0 & social < 0 ~ "Libertarians", | |
| econ < 0 & social >= 0 ~ "Populists", | |
| econ >= 0 & social >= 0 ~ "Conservatives" | |
| )) |> | |
| count(type, wt = commonweight) |> | |
| drop_na() |> | |
| mutate( | |
| prop = n / sum(n), | |
| total_n = sum(n) | |
| ) |> | |
| select(-c(total_n, n)) |> | |
| pivot_wider(names_from = type, values_from = prop) | |
| clipr::write_clip( | |
| data |> | |
| mutate(type = dplyr::case_when( | |
| econ < 0 & social < 0 ~ "Progressives", | |
| econ >= 0 & social < 0 ~ "Libertarians", | |
| econ < 0 & social >= 0 ~ "Populists", | |
| econ >= 0 & social >= 0 ~ "Conservatives" | |
| )) |> | |
| group_by(religion_rc) |> | |
| count(type, wt = commonweight) |> | |
| drop_na() |> | |
| mutate( | |
| prop = n / sum(n), | |
| total_n = sum(n), | |
| ) |> | |
| select(-c(total_n, n)) |> | |
| pivot_wider(names_from = type, values_from = prop) | |
| ) | |
| data |> | |
| count(religpew) | |
| data <- data |> | |
| mutate( | |
| # 1. Define the Broad Quadrant (Your existing logic) | |
| quadrant = dplyr::case_when( | |
| econ < 0 & social < 0 ~ "Progressive", | |
| econ >= 0 & social < 0 ~ "Libertarian (Secular)", | |
| econ < 0 & social >= 0 ~ "Populist (Left-Econ)", | |
| econ >= 0 & social >= 0 ~ "Conservative", | |
| TRUE ~ NA_character_ | |
| ), | |
| # 2. Sub-Divide the "Conservative" Quadrant | |
| subtype = dplyr::case_when( | |
| quadrant != "Conservative" ~ quadrant, | |
| # GROUP A: The "Trump" Populist | |
| # Disagrees that elections are fair (CC24_421_1) OR Supports Wall (CC24_323_3) | |
| # Note: Check if your grid variables export as _1, _2 or a, b. Usually it is _1. | |
| (CC24_421_1 >= 4 & CC24_323c == 1) ~ "Populist (Trump)", | |
| # GROUP B: The "Romney" Establishment | |
| # Supports Arms to Ukraine (CC24_308a = 4) AND Thinks Elections Fair (CC24_421_1 <= 2) | |
| (CC24_308a_4 == 1 & CC24_421_1 <= 2) ~ "Establishment", | |
| # GROUP C: The "Lee" Libertarian | |
| # Opposes Infrastructure Spending (CC24_341_4) AND Opposes Medicaid Expansion (CC24_328_5) | |
| (CC24_341d == 2 & CC24_328e == -1) ~ "Relig Libertarian", | |
| TRUE ~ "Standard" | |
| ) | |
| ) | |
| data |> | |
| filter(quadrant == "Conservative") |> | |
| count(subtype, wt = commonweight) |> | |
| drop_na() |> | |
| mutate( | |
| prop = n / sum(n) | |
| ) |> | |
| select(-n) |> | |
| pivot_wider(names_from = subtype, values_from = prop) | |
| clipr::write_clip( | |
| data |> | |
| filter(quadrant == "Conservative") |> | |
| group_by(religion_rc) |> | |
| count(subtype, wt = commonweight) |> | |
| drop_na() |> | |
| mutate( | |
| prop = n / sum(n) | |
| ) |> | |
| select(-n) |> | |
| pivot_wider(names_from = subtype, values_from = prop) |> | |
| filter(religion_rc %in% c("Mormon", "Evangelical", "Catholic", "Mainline", "Orthodox")) | |
| ) | |
| data |> | |
| filter(quadrant == "Conservative") |> | |
| group_by(religion_rc) |> | |
| count(subtype) |> | |
| filter(religion_rc == "Mormon") | |
| data |> | |
| group_by(religion_rc) |> | |
| count(quadrant) |> | |
| filter(religion_rc == "Mormon") | |
| # demographic breaks | |
| # overall Quadrant breaks | |
| # average age | |
| data |> | |
| filter(religion_rc == "Mormon") |> | |
| group_by(quadrant) |> | |
| summarise( | |
| mean_age = weighted.mean(as.numeric(2024 - birthyr), w = commonweight, na.rm = TRUE), | |
| n = n() | |
| ) | |
| # gender breakdown | |
| data |> | |
| filter(religion_rc == "Mormon") |> | |
| group_by(quadrant,gender4) |> | |
| summarise( | |
| n = n() | |
| ) |> | |
| filter(gender4 %in% c(1,2)) |> | |
| group_by(quadrant) |> | |
| mutate( | |
| prop = n / sum(n) | |
| ) | |
| # education breakdown | |
| data |> | |
| mutate(ba = dplyr::case_when( | |
| educ %in% c(1,2,3,4) ~ "No BA", | |
| educ %in% c(5,6) ~ "BA+", | |
| TRUE ~ NA_character_ | |
| )) |> | |
| filter(religion_rc == "Mormon") |> | |
| group_by(quadrant, ba) |> | |
| summarise( | |
| n = n() | |
| ) |> | |
| group_by(quadrant) |> | |
| mutate( | |
| prop = n / sum(n) | |
| ) | |
| # race breakdown | |
| data |> | |
| mutate(white = ifelse(race == 1, "White", "Non-White")) |> | |
| filter(religion_rc == "Mormon") |> | |
| group_by(quadrant, white) |> | |
| summarise( | |
| n = n() | |
| ) |> | |
| group_by(quadrant) |> | |
| mutate( | |
| prop = n / sum(n) | |
| ) | |
| # region breakdown | |
| data |> | |
| mutate(jello_belt = ifelse(inputstate %in% c(49,16), "Utah/Idaho", "Non-Jello Belt")) |> | |
| filter(religion_rc == "Mormon") |> | |
| group_by(quadrant, jello_belt) |> | |
| summarise( | |
| n = n() | |
| ) |> | |
| group_by(quadrant) |> | |
| mutate( | |
| prop = n / sum(n) | |
| ) | |
| # Subtype | |
| # average age | |
| data |> | |
| filter(religion_rc == "Mormon") |> | |
| group_by(subtype) |> | |
| summarise( | |
| mean_age = weighted.mean(as.numeric(2024 - birthyr), w = commonweight, na.rm = TRUE), | |
| n = n() | |
| ) | |
| # gender breakdown | |
| data |> | |
| filter(religion_rc == "Mormon") |> | |
| group_by(subtype,gender4) |> | |
| summarise( | |
| n = n() | |
| ) |> | |
| filter(gender4 %in% c(1,2)) |> | |
| group_by(subtype) |> | |
| mutate( | |
| prop = n / sum(n) | |
| ) | |
| # education breakdown | |
| data |> | |
| mutate(ba = dplyr::case_when( | |
| educ %in% c(1,2,3,4) ~ "No BA", | |
| educ %in% c(5,6) ~ "BA+", | |
| TRUE ~ NA_character_ | |
| )) |> | |
| filter(religion_rc == "Mormon") |> | |
| group_by(subtype, ba) |> | |
| summarise( | |
| n = n() | |
| ) |> | |
| group_by(subtype) |> | |
| mutate( | |
| prop = n / sum(n) | |
| ) | |
| # race breakdown | |
| data |> | |
| mutate(white = ifelse(race == 1, "White", "Non-White")) |> | |
| filter(religion_rc == "Mormon") |> | |
| group_by(subtype, white) |> | |
| summarise( | |
| n = n() | |
| ) |> | |
| group_by(subtype) |> | |
| mutate( | |
| prop = n / sum(n) | |
| ) | |
| # region breakdown | |
| data |> | |
| mutate(jello_belt = ifelse(inputstate %in% c(49,16), "Utah/Idaho", "Non-Jello Belt")) |> | |
| filter(religion_rc == "Mormon") |> | |
| group_by(subtype, jello_belt) |> | |
| summarise( | |
| n = n() | |
| ) |> | |
| group_by(subtype) |> | |
| mutate( | |
| prop = n / sum(n) | |
| ) | |
| # Load the dataset | |
| data <- readRDS("./data/CES/cumulative_2006-2024.rds") | |
| data <- data |> | |
| mutate(id = paste0(year, "X", case_id)) |> | |
| left_join(read.csv("./data/CES/prayer.csv"), by = "id") |> | |
| mutate(year = year.x) | |
| data <- data |> | |
| mutate( | |
| prayer_rc = case_when( | |
| prayer == 1 ~ "Several Times a Day", | |
| prayer %in% 2:7 ~ "Less Than Several Times a Day", | |
| TRUE ~ NA_character_ | |
| ), | |
| prayer_rc2 = case_when( | |
| prayer %in% 1:2 ~ "Daily or More", | |
| prayer %in% 3:7 ~ "Less Than Several Times a Day", | |
| TRUE ~ NA_character_ | |
| ) | |
| ) | |
| data$relig_church_rc <- car::recode(as.numeric(data$relig_church),"1:2 = 'Weekly or More'; 3 = 'Monthly'; 4:5 = 'A few times a year/Seldom'; 6 = 'Never'") | |
| data$relig_church_rc <- factor(data$relig_church_rc, | |
| levels = c("Weekly or More", "Monthly", "A few times a year/Seldom", "Never")) | |
| data$devout <- dplyr::case_when( | |
| data$prayer_rc == "Several Times a Day" & | |
| data$relig_imp == "Very Important" & | |
| data$relig_church_rc == "Weekly or More" ~ 1, | |
| TRUE ~ 0 | |
| ) | |
| data$cluster <- dplyr::case_when( | |
| data$prayer_rc == "Several Times a Day" & data$relig_imp == "Very Important" & data$relig_church_rc %in% c("Weekly or More") ~ "Devout Traditionalist", | |
| data$relig_church_rc %in% c("Weekly or More", "Monthly") ~ "Adaptive Believer", | |
| TRUE ~ "Cultural Mormon" | |
| ) | |
| data$year_4 <- car::recode(as.numeric(data$year), "2008:2012 = '2008-12'; 2013:2016 = '2013-16'; 2017:2020 = '2017-20'; 2021:2024 = '2021-24'") | |
| data$year_4 <- factor(data$year_4, | |
| levels = c("2008-12", "2013-16", "2017-20", "2021-24")) | |
| plot <- data |> | |
| filter(religion == 3) |> | |
| group_by(year_4) |> | |
| count(cluster, wt = weight) |> | |
| drop_na() |> | |
| mutate( | |
| prop = n / sum(n), | |
| total_n = sum(n), | |
| lower = binom.confint(x = n, n = total_n, method = "asymptotic")$lower, | |
| upper = binom.confint(x = n, n = total_n, method = "asymptotic")$upper | |
| ) |> | |
| ggplot(aes(x = year_4, y = prop, group = cluster)) + | |
| geom_line(aes(color = cluster)) + | |
| geom_point( | |
| size = 3, | |
| stroke = 1.5, | |
| aes(color = cluster) | |
| ) + | |
| geom_errorbar(aes(ymin = lower, ymax = upper, color = cluster), width = 0.2) + | |
| geom_text(aes(label = scales::percent(prop, accuracy = 1)), vjust = -1, size = 4, family = "Cairo", fontface = "bold", color = "black") + | |
| labs( | |
| title = "LDS Cluster Sizes Shift Over Time", | |
| subtitle = "Devout Trad. = praying several times a day, religion very important, and attending church weekly+\nAdaptive = attending church at least monthly (+ not devout traditionalist)\nCultural = everyone else", | |
| x = "Year Group", | |
| y = "Proportion", | |
| caption = "@mormon_metrics\nData: Cooperative Election Study (CES) 2008-24. N=9,189 LDS" | |
| ) + | |
| theme_minimal() + | |
| scale_y_continuous(labels = scales::percent_format(accuracy = 1), limits = c(0,0.8) , breaks = seq(0, 0.8, by = 0.1)) + | |
| theme( | |
| axis.ticks = element_blank(), | |
| axis.title = element_text(size = 14), | |
| axis.text.y = element_text(size = 10), | |
| axis.text.x = element_text(size = 10, margin = margin(t = -5)), | |
| plot.background = element_rect(fill = "grey95"), # Change entire plot background color here | |
| panel.background = element_blank(), | |
| text = element_text(face = "bold", family = "Cairo"), | |
| plot.title = element_text(size = 15, face = "bold"), | |
| plot.subtitle = element_text(size = 8), | |
| plot.title.position = "plot", | |
| plot.subtitle.position = "plot", | |
| legend.title = element_blank(), | |
| legend.background = element_blank(), | |
| legend.box.background = element_blank(), | |
| legend.key = element_blank(), | |
| panel.grid = element_blank(), | |
| legend.position = "top", | |
| panel.grid.major.y = element_line(color = "lightgrey", linetype = 'solid'), | |
| plot.caption = element_text(size = 8,family = "Cairo") | |
| ) | |
| ggsave("./images/26_political_compass_cluster.png", plot, width = 1500, height = 1500, units = "px", dpi = 300) | |
| # gist: https://gist.github.com/acbass49/8b69a5abf126afaa89eb1e4418b659e9 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment