-
-
Save danweitzel/b82f6c4105e64b05609e84e8ef262be1 to your computer and use it in GitHub Desktop.
Some of the graphs I presented at the International Symposium of the International Studies Center
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
## This R Script has code for some of the visualizations I made for my talk | |
## at the CSU International Symposium on Democracy | |
# Install Packages | |
if(!require('pacman')) { | |
install.packages('pacman') | |
library('pacman') | |
} | |
# loading the p_load function | |
p_load(devtools, tidyverse, scales,haven,sjlabelled, | |
ggrepel, viridis, ggthemes, maps, countrycode, | |
install = TRUE) | |
devtools::install_github("vdeminstitute/vdemdata") | |
install_github("jamesmartherus/anesr") | |
library(vdemdata) | |
library(anesr) | |
# Generate a world map with changes between 2002 and 2022 | |
df_vdem_map <- | |
vdem |> | |
dplyr::select(country_name, country_id, year, | |
v2x_polyarchy, v2x_libdem, v2x_partipdem, v2x_egaldem) |> | |
filter(year %in% c(2002, 2022)) |> | |
group_by(country_name) |> | |
mutate(delta_polyarchy = v2x_polyarchy - lag(v2x_polyarchy)) |> | |
filter(year == 2022) | |
world_map = map_data("world") | |
world_map$country_id <- countrycode(world_map$region, origin = 'country.name', destination = 'vdem') | |
df_democracy <- | |
world_map |> | |
left_join(df_vdem_map) | |
world_map = map_data("world") %>% | |
filter(! long > 180) | |
world_map$country_id <- countrycode(world_map$region, origin = 'country.name', destination = 'vdem') | |
df_democracy <- | |
world_map |> | |
left_join(df_vdem_map) | |
countries = df_democracy %>% | |
distinct(region,delta_polyarchy) | |
countries %>% | |
filter(region != "Antarctica") |> | |
ggplot(aes(fill = delta_polyarchy, map_id = region)) + | |
geom_map(map = world_map) + | |
expand_limits(x = world_map$long, y = world_map$lat) + | |
scale_fill_viridis(option="inferno") + theme_bw() + | |
labs(x = "Longitude", y = "Lattitude", | |
fill='Change in Democracy', | |
title = "Democracy around the world", | |
subtitle = "V-Dem's Polyarchy between 2002 and 2022") + | |
theme(legend.position="bottom") + | |
coord_map("moll") + | |
theme_map() + theme(text=element_text(size=15)) | |
# Delta Plot of democracy scores for a country in 2002 and 2022 | |
vdem |> | |
dplyr::select(country_name, year, v2x_polyarchy) |> | |
group_by(country_name) |> | |
filter(year %in% c(2002, 2022)) |> | |
mutate(delta_polyarchy = v2x_polyarchy - lag(v2x_polyarchy), | |
lag_polyarchy = lag(v2x_polyarchy), | |
pos_dummy = ifelse(delta_polyarchy >=0, "positive", "negative")) |> | |
drop_na() |> | |
filter(year == 2022) |> | |
ggplot(aes(y = v2x_polyarchy, x = lag_polyarchy, color = pos_dummy, label = country_name)) + | |
geom_point(alpha = 1/2) + theme_bw() + | |
geom_abline(intercept = 0, slope = 1, color = "black", linetype = "dashed") + | |
ylim(0,1) + xlim(0,1) + geom_text_repel() + theme(legend.position = "none") + | |
labs(title = "Changes in Polyarchy between 2002 and 2022", | |
caption = "Note: Analysis based on V-Dem Version 14", | |
y = "Polyarchy, 2022", | |
x = "Polyarchy, 2002") + theme(text=element_text(size=15)) | |
# Gobal democracy average since 1789 | |
vdem |> | |
group_by(year) |> | |
summarize(mean_polyarchy = mean(v2x_polyarchy, na.rm = TRUE), n = n()) |> | |
ggplot(aes(y = mean_polyarchy, x = year)) + | |
geom_line() + | |
theme_bw() + | |
labs(title = "Average Democracy in the World", | |
caption = "Note: Analysis based on V-Dem Version 14", | |
x = "Year", | |
y = "V-Dem Polyarchy, global average") + | |
ylim(0,1)+ theme(text=element_text(size=15))+ | |
annotate('rect', xmin=2008, xmax=2024, ymin=0.4, ymax=0.62, alpha=.2, fill='red') | |
## Examining attitudes of American voters | |
data(timeseries_2020) | |
data(timeseries_cum) #Load Time Series Cumulative File (1948-2016) | |
# 2020 is missing from the cumulative file. The code below prepares 2020 for a merge | |
# with the cumulative file | |
df_anes_2020 <- | |
timeseries_2020 |> | |
remove_all_labels() |> | |
dplyr::select(V201156, V201157, V201228, V201229, V201230, V201231x, V200010a) |> | |
mutate(VCF0004 = 2020) |> | |
rename(year = VCF0004)|> # Year of response | |
mutate(pid_3 = ifelse(V201231x %in% c(1,2, 3), "Democrat", | |
ifelse(V201231x %in% c(5,6,7), "Republican", | |
ifelse(V201231x == 4, "Independent", NA)))) |> | |
rename(pid_7 = V201231x)|> #7 scale Party ID val: 1-7. Strong Democrat 2. Weak Democrat3. Independent - Democrat4. Independent - Independent5. Independent - Republican6. Weak Republican7. Strong Republican | |
#rename(pid_3 = V201228)|> # | |
rename(weight = V200010a) |> | |
rename(therm_dem = V201156)|> # val 00-96 cold-warm as coded; 97: 97-100, 98: DK, 99. NA | |
rename(therm_rep = V201157) |> # val 00-96 cold-warm as coded; 97: 97-100, 98: DK, 99. NA | |
mutate(therm_dem = ifelse(therm_dem <0 | therm_dem > 100 , NA, therm_dem), | |
therm_dem = ifelse(therm_dem %in% c(97,98,99,100), 97, therm_dem), | |
therm_rep =ifelse(therm_rep <0 | therm_rep > 100, NA, therm_rep), | |
therm_rep = ifelse(therm_rep %in% c(97,98,99,100), 97, therm_rep), | |
strong_partisan = if_else(pid_7 == 1|pid_7 ==7, 1, 0), | |
pid_7_num = as.numeric(pid_7), | |
pid_7 = recode(pid_7, | |
"1" = "Strong Democrat", | |
"2" = "Weak Democrat", | |
"3" = "Independent - Democrat", | |
"4" = "Independent - Independent", | |
"5" = "Independent - Republican", | |
"6" = "Weak Republican", | |
"7" = "Strong Republican"), | |
pid_7 = reorder(pid_7, pid_7_num), | |
pid_3_num = as.numeric(pid_3), | |
pid_3 = recode(pid_3, | |
"1" = "Democrat", | |
"3" = "Independent", | |
"2" = "Republican"), | |
pid_3 = reorder(pid_3, pid_3_num), | |
pid_3_sort = factor(recode(pid_7_num, #different from regular pid_3 which codes 3, 5 as partisan | |
"1" = "Democrat", | |
"2" = "Democrat", | |
"3" = "Independent", | |
"4" = "Independent", | |
"5" = "Independent", | |
"6" = "Republican", | |
"7" = "Republican"), | |
levels = c("Democrat", | |
"Independent", | |
"Republican")), | |
pid_2_sort = na_if(pid_3_sort, "Independent"), #better just to filter(pid_3_sort != "Independent"), but used to build other vars | |
pid_2 = na_if(pid_3, "Independent"), | |
therm_inparty = if_else(pid_3=="Democrat", therm_dem, therm_rep), | |
therm_inparty = if_else(pid_3=="Democrat" | pid_3 == "Republican", | |
if_else(pid_3=="Democrat", therm_dem, therm_rep), | |
(therm_dem + therm_rep)/2), #therm in/out are equal | |
therm_inparty = na_if(therm_inparty, -9), | |
therm_outparty = if_else(pid_3=="Democrat" | pid_3 == "Republican", | |
if_else(pid_3=="Democrat", therm_rep, therm_dem), | |
(therm_dem + therm_rep)/2), | |
npa_party = therm_inparty - therm_outparty, | |
therm_parties_mean = (therm_dem + therm_rep)/2) | |
# The cumulative file | |
df_anes <- | |
timeseries_cum |> | |
remove_all_labels() |> | |
dplyr::select(VCF0004, VCF0301, VCF0303, VCF0305, VCF0311, VCF0312, VCF0803, | |
VCF0218, VCF0224, VCF0201, VCF0202,VCF0009z) |> | |
rename(year = VCF0004)|> # Year of response | |
rename(pid_7 = VCF0301)|> #7 scale Party ID val: 1-7. Strong Democrat 2. Weak Democrat3. Independent - Democrat4. Independent - Independent5. Independent - Republican6. Weak Republican7. Strong Republican | |
rename(pid_3 = VCF0303)|> # Party ID 3 categories val: "Republican", "Independent", "Democrat" (Dem/Rep include Leaners) | |
rename(pid_str = VCF0305)|> # PID strength val: 1. Independent 2. Leaning Independent 3. Weak Partisan 4. Strong Partisan Kept this because I wanted to create basically this variable later | |
rename(win_care_pres = VCF0311)|> # How much do you care which party wins presidency? val: 1. Don't care very much or DK, pro-con, depends, and other, 2. Care a great deal | |
rename(win_care_cong = VCF0312)|> # How much do you care which party wins congress? val: 1. Don't care very much or DK, pro-con, depends, and other, 2. Care a great deal notes: only asked through 2008 | |
rename(respondent_ideo = VCF0803)|> # Liberal-conservative scale val: 1(extremely liberal)- 7(extremely conservative) 9. DK; haven't much thought about it | |
rename(therm_dem = VCF0218)|> # val 00-96 cold-warm as coded; 97: 97-100, 98: DK, 99. NA | |
rename(therm_rep = VCF0224) |> # val 00-96 cold-warm as coded; 97: 97-100, 98: DK, 99. NA | |
rename(therm_dem_old = VCF0201) |> | |
rename(therm_rep_old = VCF0202) |> | |
rename(weight = VCF0009z) |> | |
mutate(therm_dem = na_if(therm_dem, 98), | |
therm_dem = na_if(therm_dem, 99), | |
therm_rep = na_if(therm_rep, 98), | |
therm_rep = na_if(therm_rep, 99), | |
respondent_ideo = na_if(respondent_ideo, 9), #the recode() function is used in the next 4 pipes to apply new values to observation in the columns. ANES uses numerical values to represent factors. | |
strong_partisan = if_else(pid_7 == 1|pid_7 ==7, 1, 0), | |
pid_7_num = as.numeric(pid_7), | |
pid_7 = recode(pid_7, | |
"1" = "Strong Democrat", | |
"2" = "Weak Democrat", | |
"3" = "Independent - Democrat", | |
"4" = "Independent - Independent", | |
"5" = "Independent - Republican", | |
"6" = "Weak Republican", | |
"7" = "Strong Republican"), | |
pid_7 = reorder(pid_7, pid_7_num), | |
pid_3_num = as.numeric(pid_3), | |
pid_3 = recode(pid_3, | |
"1" = "Democrat", | |
"2" = "Independent", | |
"3" = "Republican"), | |
pid_3 = reorder(pid_3, pid_3_num), | |
pid_str_num = as.numeric(pid_str), | |
pid_str = recode(pid_str, | |
"1" = "Independent", | |
"2" = "Leaning Independent", | |
"3" = "Weak Partisan", | |
"4" = "Strong Partisan"), | |
pid_str = reorder(pid_str, pid_str_num), | |
respondent_ideo_num = as.numeric(respondent_ideo), | |
respondent_ideo = recode(respondent_ideo, | |
"1" = "Extremely Liberal", | |
"2" = "Liberal", | |
"3" = "Somewhat Liberal", | |
"4" = "Moderate", | |
"5" = "Somewhat Conservative", | |
"6" = "Conservative", | |
"7" = "Extremely Conservative"), | |
respondent_ideo = reorder(respondent_ideo, respondent_ideo_num), | |
pid_3_sort = factor(recode(pid_7_num, #different from regular pid_3 which codes 3, 5 as partisan | |
"1" = "Democrat", | |
"2" = "Democrat", | |
"3" = "Independent", | |
"4" = "Independent", | |
"5" = "Independent", | |
"6" = "Republican", | |
"7" = "Republican"), | |
levels = c("Democrat", | |
"Independent", | |
"Republican")), | |
pid_2_sort = na_if(pid_3_sort, "Independent"), #better just to filter(pid_3_sort != "Independent"), but used to build other vars | |
pid_2 = na_if(pid_3, "Independent"), | |
therm_inparty = if_else(pid_3=="Democrat", therm_dem, therm_rep), | |
therm_inparty = if_else(pid_3=="Democrat" | pid_3 == "Republican", | |
if_else(pid_3=="Democrat", therm_dem, therm_rep), | |
(therm_dem + therm_rep)/2), #therm in/out are equal | |
therm_inparty = na_if(therm_inparty, -9), | |
therm_outparty = if_else(pid_3=="Democrat" | pid_3 == "Republican", | |
if_else(pid_3=="Democrat", therm_rep, therm_dem), | |
(therm_dem + therm_rep)/2), | |
npa_party = therm_inparty - therm_outparty, | |
therm_parties_mean = (therm_dem + therm_rep)/2, | |
therm_dem_old = na_if(therm_dem_old, 98), | |
therm_dem_old = na_if(therm_dem_old, 99), | |
therm_rep_old = na_if(therm_rep_old, 98), | |
therm_rep_old = na_if(therm_rep_old, 99), | |
therm_party_ingroup = if_else(pid_2_sort=="Democrat", therm_dem_old, therm_rep_old), | |
therm_party_outgroup = if_else(pid_2_sort=="Democrat", therm_rep_old, therm_dem_old), | |
npa_partisans = therm_party_ingroup - therm_party_outgroup) |> | |
bind_rows(df_anes_2020) | |
# Prepare a data frame for visualizations | |
fig_1_df <- df_anes %>% | |
mutate(independent_count = str_count(pid_7, "Independent"), # Code here moves leaners into partisan coding | |
pid_3_lean = ifelse(str_detect(pid_7, "Republican"), "Republican", | |
ifelse(str_detect(pid_7, "Democrat"), "Democrat", | |
ifelse(independent_count == 2, "Independent", NA)))) |> | |
dplyr::select(-pid_3) |> | |
rename(pid_3 = pid_3_lean) |> | |
filter(pid_3 != "Independent") %>% | |
#filter(pid_3 != "Independent")%>% | |
# filter(year <= 2008)%>% #un/comment this line for the original data. | |
filter(year >= 1978)%>% | |
select(year, | |
weight, | |
pid_3, | |
therm_inparty, | |
therm_outparty) %>% | |
pivot_longer(therm_inparty:therm_outparty, names_to = "ft_towards", values_to = "ft")%>% | |
unite("group", pid_3:ft_towards)%>% | |
mutate(group = recode(group, | |
"Democrat_therm_inparty" = "Democrat - In Party", | |
"Democrat_therm_outparty" = "Democrat - Out Party", | |
"Republican_therm_inparty" = "Republican - In Party", | |
"Republican_therm_outparty" = "Republican - Out Party"))%>% | |
group_by(year, group)%>% | |
summarize(mean = weighted.mean(ft, weight, na.rm = TRUE), | |
#mean = mean(ft, na.rm = TRUE), | |
sd = sd(ft, na.rm = TRUE), | |
n = n()) |> | |
separate(group, into = c("party", "group_type"), sep = " - ", remove = FALSE) | |
# In and out party affect over time | |
fig_1_df |> | |
filter(year >= 1978) |> | |
#filter(str_detect(group_type, "In")) |> | |
mutate(mean = ifelse(str_detect(group_type, "Out"), NA, mean)) |> | |
ggplot(aes(x = year, y=mean)) + | |
geom_point(aes(shape = group_type, color = party)) + | |
geom_smooth(aes(linetype = group_type, color = party), se=F)+ | |
scale_color_manual(values = c("blue", "red"))+ theme_bw() + | |
scale_linetype_manual(values = c("In Party" = "solid", | |
"Out Party" = "dashed", | |
"In Party" = "solid", | |
"Out Party" = "dashed")) + | |
scale_shape_manual(values = c("In Party" = 3, | |
"Out Party" = 2)) + | |
scale_x_continuous(breaks = seq(1976, 2020, by = 4)) + | |
scale_y_continuous(limits = c(10,80)) + | |
theme(legend.position = "none") + | |
labs(title = "Partisan In and Outgroup Feeling Thermometer", | |
caption = "Solid lines: In group, Dashed lines: Out group, Leaners coded as partisans", | |
y = "Mean Thermometer Ratings of Partisans", | |
x = "Year")+ theme(text=element_text(size=15)) | |
# The difference between in and out party affect | |
df_anes |> | |
dplyr::select(year, pid_3, therm_inparty, therm_outparty, weight) |> | |
drop_na(pid_3) |> | |
filter(pid_3 != "Independent")%>% | |
mutate(delta_therm = therm_inparty- therm_outparty) |> | |
group_by(year) |> | |
summarize(mean = weighted.mean(delta_therm, weight, na.rm = TRUE), | |
sd = sd(delta_therm, na.rm = TRUE), | |
n = n()) |> | |
filter(year >= 1978) |> | |
ggplot(aes(x = year, y = mean)) + | |
geom_point() + | |
geom_smooth(color = "gray50", se=T) + | |
scale_x_continuous(breaks = seq(1976, 2020, by = 4)) + | |
theme_bw() + | |
theme(legend.position = "none") + | |
labs(title = "Affective Polarization", | |
caption = "Note: Analysis based on American National Election Study data.", | |
y = "Average Difference between In and Outgroup Affect", | |
x = "Year")+ theme(text=element_text(size=15)) | |
# The difference between in and out party affect by partisans | |
df_anes |> | |
dplyr::select(year, pid_3, therm_inparty, therm_outparty, weight) |> | |
drop_na(pid_3) |> | |
filter(pid_3 != "Independent")%>% | |
mutate(delta_therm = therm_inparty- therm_outparty) |> | |
group_by(year, pid_3) |> | |
summarize(mean = weighted.mean(delta_therm, weight, na.rm = TRUE), | |
sd = sd(delta_therm, na.rm = TRUE), | |
n = n()) |> | |
filter(year >= 1978) |> | |
ggplot(aes(x = year, y = mean, group = pid_3, color = pid_3)) + | |
geom_point() + | |
geom_smooth(aes(color = pid_3), se=F) + | |
scale_x_continuous(breaks = seq(1976, 2020, by = 4)) + | |
scale_color_manual(values = c("red", "blue"))+ theme_bw() + | |
theme(legend.position = "none") + | |
labs(title = "Affective Polarization", | |
caption = "Note: Analysis based on American National Election Study data.", | |
y = "Average Difference between In and Outgroup Affect", | |
x = "Year")+ theme(text=element_text(size=15)) | |
# US Party Analysis | |
# Loading in the V-Dem VParty data set | |
df_vparty <- vparty |> | |
mutate(v2paopresp = scales::rescale(v2paopresp), | |
v2xpa_antiplural = scales::rescale(v2xpa_antiplural), | |
v2xpa_popul = scales::rescale(v2xpa_popul), | |
v2paviol = scales::rescale(v2paviol)) |> | |
filter(country_name == "United States of America") |> | |
dplyr::select(country_name, year,v2paenname, v2paopresp,v2xpa_antiplural, | |
v2xpa_popul, v2paviol) | |
## Plotting rejection of political violence by U.S. political parties over time | |
df_vparty |> | |
drop_na(v2paviol) |> | |
ggplot(aes(x = year, y = v2paviol, color = v2paenname)) + | |
geom_line() + | |
scale_color_manual(values = c("blue", "red")) + | |
theme_bw() + | |
labs(title = "Rejection of political violence by U.S. political parties", | |
x = "Year", | |
y = "Rejection of political violence", | |
subtitle = "Analysis based on V-Party Version 2", | |
caption = "Question: To what extent does the leadership of this party explicitly discourage the use of violence | |
against domestic political opponents?", | |
color = "Party:") + ylim(0,1)+ | |
theme(legend.position = "bottom") + theme(text=element_text(size=15)) | |
## Plotting attacks against political opponents by U.S. political parties over time | |
df_vparty |> | |
drop_na(v2paopresp) |> | |
ggplot(aes(x = year, y = v2paopresp, color = v2paenname)) + | |
geom_line() + | |
scale_color_manual(values = c("blue", "red")) + | |
theme_bw() + | |
labs(title = "Attacks against political opponents by U.S. political parties", | |
subtitle = "Analysis based on V-Party Version 2", | |
x = "Year", | |
y = "Political opponents", | |
color = "Party:", | |
caption = "Question: Prior to this election, have leaders of this party used severe personal attacks or tactics of | |
demonization against their opponents?") +ylim(0,1)+ | |
theme(legend.position = "bottom")+ theme(text=element_text(size=15)) | |
## Plotting populism by U.S. political parties over time | |
df_vparty |> | |
drop_na(v2xpa_popul) |> | |
ggplot(aes(x = year, y = v2xpa_popul, color = v2paenname)) + | |
geom_line() + | |
scale_color_manual(values = c("blue", "red")) + | |
theme_bw() + | |
labs(title = "Populism in U.S. political parties", | |
subtitle = "Analysis based on V-Party Version 2", | |
x = "Year", | |
y = "Populism Index", | |
color = "Party:", | |
caption = "Question: To what extent do representatives of the party use populist rhetoric?") + | |
theme(legend.position = "bottom") + ylim(0,1)+theme(text=element_text(size=15)) | |
## Plotting anti-pluralism by U.S. political parties over time | |
df_vparty |> | |
drop_na(v2xpa_antiplural) |> | |
ggplot(aes(x = year, y = v2xpa_antiplural, color = v2paenname)) + | |
geom_line() + | |
scale_color_manual(values = c("blue", "red")) + | |
theme_bw() + | |
labs(title = "Anti-pluralism in U.S. political parties", | |
subtitle = "Analysis based on V-Party Version 2", | |
x = "Year", | |
y = "Anti-Pluralism Index", | |
color = "Party:", | |
caption = "Question = To what extent does the party show a lacking commitment to democratic norms prior to | |
elections?") +ylim(0,1)+ | |
theme(legend.position = "bottom") + theme(text=element_text(size=15)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment