Skip to content

Instantly share code, notes, and snippets.

@danweitzel
Created April 2, 2024 19:59
Show Gist options
  • Save danweitzel/b82f6c4105e64b05609e84e8ef262be1 to your computer and use it in GitHub Desktop.
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 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