This vignette shows how to replicate and extend the charts in chapter 10 of my book Non-democratic Politics: Authoritarianism, Dictatorships, and Democratization (Palgrave Macmillan, 2016). It assumes that you have downloaded the replication package as follows:
if(!require(devtools)) { install.packages("devtools") } devtools::install_github('xmarquez/AuthoritarianismBook')
It also assumes you have the dplyr
, ggplot2
, scales
, forcats
, broom
, reshape2
, tidyr
, purrr
, and knitr
packages installed:
if(!require(dplyr)) { install.packages("dplyr") } if(!require(ggplot2)) { install.packages("ggplot2") } if(!require(scales)) { install.packages("forcats") } if(!require(forcats)) { install.packages("scales") } if(!require(broom)) { install.packages("broom") } if(!require(reshape2)) { install.packages("reshape2") } if(!require(purrr)) { install.packages("purrr") } if(!require(tidyr)) { install.packages("tidyr") } if(!require(knitr)) { install.packages("knitr") }
For the interactive graph below, you also need the plotly
package:
if(!require(plotly)) { install.packages("plotly") }
knitr::opts_chunk$set(fig.height = 7, fig.width = 7)
This table shows the frequency of different types of regime transition, 1945-2010. This table counts only countries that have experienced transitions. Regime change is rare; in the period 1945-2010, only about 5% of all country-years experienced regime transitions. Regime data comes from @GeddesWrightFrantz2014. `Other' category includes instances of state breakdown, foreign occupation, and state termination (e.g., after unification with a larger state).
library(AuthoritarianismBook) library(dplyr) library(ggplot2) library(reshape2) data <- all_gwf_periods %>% mutate(gwf_previous = ifelse(grepl("democracy", gwf_full_regimetype), "Democracy", ifelse(grepl("military|oligarchy|personal|party|monarchy", gwf_full_regimetype), "Non-democracy", "Other"))) %>% group_by(country_name) %>% mutate(gwf_next = lead(gwf_previous)) %>% ungroup() %>% count(gwf_previous, gwf_next, sort=TRUE) %>% filter(!is.na(gwf_next)) %>% ungroup() %>% mutate(total_trans = sum(n), prop_trans = scales::percent_format()(n/total_trans)) data %>% dcast(gwf_previous ~ gwf_next, value.var="prop_trans") %>% knitr::kable(col.names = c("Previous regime", "To democracy", "To non-democracy", "To other"))
This table simply shows the total number of transitions, rather than the proportions in the datatset:
data %>% dcast(gwf_previous ~ gwf_next, value.var="n") %>% knitr::kable(col.names = c("Previous regime", "To democracy", "To non-democracy", "To other"), caption = "Total number of transition events in the dataset")
Here we see the proportions per row:
data %>% group_by(gwf_previous) %>% mutate(total_by_row = sum(n), prop_trans = scales::percent_format()(n/total_by_row)) %>% dcast(gwf_previous ~ gwf_next, value.var="prop_trans") %>% knitr::kable(col.names = c("Previous regime", "To democracy", "To non-democracy", "To other"), caption = "Proportions by row (previous regime)")
More than 98 per cent of transitions from democracy are to non-democracy; only 36 per cent of transitions from non-democracy are to democracy, and nearly 50 per cent are to other forms of non-democracy.
data %>% group_by(gwf_next) %>% mutate(total_by_column = sum(n), prop_trans = scales::percent_format()(n/total_by_column)) %>% dcast(gwf_previous ~ gwf_next, value.var="prop_trans") %>% knitr::kable(col.names = c("Previous regime", "To democracy", "To non-democracy", "To other"), caption = "Proportions by column (successor regime)")
More than 76 per cent of transitions to democracy are from non-democracy; the rest are from situations of no authority.
It is possible to calculate the frequencies of transition per year, including the years where no transition occurred. As we see below, regime change is extremely rare: more than 97 per cent of the country years in democratic regimes, and more than 95 per cent of the country years in non-democratic regimes, do not experience transitions:
data <- all_gwf %>% mutate(gwf_previous = ifelse(grepl("democracy", gwf_full_regimetype), "Democracy", ifelse(grepl("military|oligarchy|personal|party|monarchy", gwf_full_regimetype), "Non-democracy", "Other"))) %>% group_by(country_name) %>% mutate(transition = gwf_casename != lead(gwf_casename), gwf_next = lead(gwf_previous), gwf_next = ifelse(!transition, "No transition", gwf_next)) %>% ungroup() %>% count(gwf_previous, gwf_next, sort=TRUE) %>% filter(!is.na(gwf_next)) %>% ungroup() %>% mutate(total_trans = sum(n), prop_trans = scales::percent_format()(n/total_trans)) data %>% dcast(gwf_previous ~ gwf_next, value.var="n") %>% select(gwf_previous, `No transition`, everything()) %>% knitr::kable(col.names = c("Regime", "Number of country-years with no transition", "To democracy", "To non-democracy", "To other")) data %>% dcast(gwf_previous ~ gwf_next, value.var="prop_trans") %>% select(gwf_previous, `No transition`, everything()) %>% knitr::kable(col.names = c("Regime", "Prop. of country-years with no transition", "To democracy", "To non-democracy", "To other")) # This is more informative by row data %>% group_by(gwf_previous) %>% mutate(total_by_row = sum(n), prop_trans = scales::percent_format()(n/total_by_row)) %>% dcast(gwf_previous ~ gwf_next, value.var="prop_trans") %>% select(gwf_previous, `No transition`, everything()) %>% knitr::kable(col.names = c("Regime", "Prop. of country-years with no transition", "To democracy", "To non-democracy", "To other"))
This figure is a scatterplot of GDP per capita vs. democracy. GDP data is the median of the per capita value from the Maddison project [@Maddison2013], the Penn World Tables [@Feenstra2013], and the World Bank; democracy data from @Pemstein2010, extended by me [@Marquez2016]. Each point represents a country-year; each line represents a country trajectory over those years where income and democracy data exists. Highlighted points are regimes classified as monarchies by @MagaloniChuMin2013 for the 1950-2013 period, as well as other regimes in the Middle East (including regimes for the period before 1950).
data <- inner_join(extended_uds, economic_data) %>% group_by(country_name, GWn, year, index) %>% summarise(median = median(per_capita, na.rm = TRUE)) %>% filter(!is.na(median)) data <- data %>% left_join(magaloni) %>% mutate(regime_nr = ifelse(regime_nr == "Monarchy", "monarchy", NA), region = ifelse(country_name %in% c("Algeria", "Bahrain", "Egypt", "Iraq", "Israel", "Jordan", "Kuwait", "Lebanon", "Libya", "Morocco", "Oman", "Qatar", "Saudi Arabia", "South Sudan", "Sudan", "Syria", "Tunisia", "Turkey (Ottoman Empire)", "United Arab Emirates", "Yemen (Arab Republic of Yemen)", "Yemen, People's Republic of"), "Middle East", ifelse(country_name == "Singapore", "Singapore", NA)), region_regime = ifelse(!is.na(regime_nr) & !is.na(region), paste(region, regime_nr), region)) ggplot(data = data, aes(x = index, y = median, group = GWn)) + geom_path(alpha = 0.1) + geom_point(aes(color = region_regime), alpha = 0.5) + theme_bw() + scale_y_log10(label=scales::dollar) + geom_smooth(aes(y = median,group=0), method = "lm", color = "red") + labs(y="GDP per capita, median of various measures", x="Unified democracy score", shape="", alpha="", color="") + geom_text(data = data %>% ungroup() %>% filter(!is.na(region_regime), (year %in% c(min(year), max(year))) | ((year %% 10) == 0)), aes(label = year, color = region_regime), check_overlap = TRUE) + geom_vline(xintercept = 0.5, linetype=2) + theme(legend.position = "bottom") + scale_color_discrete(na.value = "lightgrey") + guides(shape = guide_legend(ncol=2))
This correlation does not vary much depending on the measure of GDP per capita:
data <- inner_join(extended_uds, economic_data) %>% filter(!is.na(per_capita)) ggplot(data = data, aes(x = index, y = per_capita, group = GWn)) + geom_path(alpha = 0.1) + geom_point(alpha = 0.5) + theme_bw() + scale_y_log10(label=scales::dollar) + geom_smooth(aes(y = per_capita, group = variable), method = "lm", color = "red") + labs(y="GDP per capita, various measures", x="Unified democracy score", shape="", alpha="", color="") + geom_text(data = data %>% ungroup() %>% filter((year %in% c(min(year), max(year))) | ((year %% 25) == 0)), aes(label = year), check_overlap = TRUE) + geom_vline(xintercept = 0.5, linetype=2) + theme(legend.position = "bottom") + scale_color_discrete(na.value = "lightgrey") + guides(shape = guide_legend(ncol=2)) + facet_wrap(~variable, ncol = 1)
Or democracy:
data <- full_join(vdem, economic_data) %>% group_by(country_name, GWn, year, v2x_polyarchy, v2x_api, v2x_mpi, v2x_libdem, v2x_partipdem, v2x_delibdem, v2x_egaldem) %>% summarise(median = median(per_capita, na.rm = TRUE)) %>% filter(!is.na(median)) %>% melt(measure.vars = c("v2x_polyarchy", "v2x_api", "v2x_mpi", "v2x_libdem", "v2x_partipdem", "v2x_delibdem", "v2x_egaldem")) ggplot(data = data, aes(x = value, y = median, group = GWn)) + geom_path(alpha = 0.1) + geom_point(alpha = 0.5) + theme_bw()+ scale_y_log10(label=scales::dollar) + geom_smooth(aes(y = median, group = variable), method = "lm", color = "red") + labs(y="GDP per capita, median of various measures", x="Democracy score, VDem", shape="", alpha="", color="") + geom_text(data = data %>% ungroup() %>% filter((year %in% c(min(year), max(year))) | ((year %% 25) == 0)), aes(label = year), check_overlap = TRUE) + geom_vline(xintercept = 0.5, linetype=2) + theme(legend.position = "bottom") + scale_color_discrete(na.value = "lightgrey") + guides(shape = guide_legend(ncol=2)) + facet_wrap(~variable, ncol = 1)
But the correlation does vary from country to country, and depends a bit on the measure of GDP used:
library(broom) library(purrr) library(tidyr) data <- left_join(extended_uds, economic_data) %>% group_by(primary_source, variable, country_name) %>% filter(!is.na(per_capita), n() > 5) %>% summarise(index = list(index), per_capita = list(per_capita)) %>% mutate(cor_test = map2(index, per_capita, ~ tidy(cor.test(.x, log(.y))))) %>% unnest(cor_test) %>% ungroup() ggplot(data = data, aes(x = forcats::fct_reorder(country_name, estimate, na.rm =TRUE), y = estimate)) + geom_pointrange(aes(ymin = conf.low, ymax = conf.high, color = primary_source)) + labs(x = "", y = "Estimated correlation", color = "Primary source of GDP data") + theme_bw() + theme(legend.position = "bottom") + guides(color = guide_legend(ncol=2)) + geom_hline(yintercept = 0, color = "red") + coord_flip()
We can also do this as follows:
data <- left_join(extended_uds, economic_data) %>% group_by(primary_source, variable, country_name) %>% filter(!is.na(per_capita), n() > 5) %>% summarise(index = list(index), per_capita = list(per_capita)) %>% mutate(cor_test = map2(index, per_capita, ~ tidy(cor.test(.x, log(.y))))) %>% unnest(cor_test) %>% group_by(country_name) %>% summarise(avg_estimate = mean(estimate), se_estimate = sqrt(sum(((estimate - conf.high)/1.96)^2))/n(), conf.high = avg_estimate + 1.96*se_estimate, conf.low = avg_estimate - 1.96*se_estimate) ggplot(data = data, aes(x = forcats::fct_reorder(country_name, avg_estimate, na.rm =TRUE), y = avg_estimate)) + geom_pointrange(aes(ymin = conf.low, ymax = conf.high)) + labs(x = "", y = "Estimated correlation", color = "Primary source of GDP data") + theme_bw() + theme(legend.position = "bottom") + guides(color = guide_legend(ncol=2)) + geom_hline(yintercept = 0, color = "red") + coord_flip()
Raw (uncontrolled) correlation between economic development and democracy, per year. Shaded areas represent 95% confidence intervals. GDP data from the Maddison Project [@Maddison2013], the Penn World Tables [@Feenstra2013], and the World Bank; democracy data from @Pemstein2010, extended by the me [@Marquez2016].
data <- left_join(extended_uds, economic_data) %>% group_by(primary_source, variable, year) %>% filter(!is.na(per_capita), n() > 4) %>% summarise(index = list(index), per_capita = list(per_capita)) %>% mutate(cor_test = map2(index, per_capita, ~ tidy(cor.test(.x, log(.y))))) %>% unnest(cor_test) %>% group_by(year) %>% summarise(median = median(estimate, na.rm=TRUE), min_conf_low = min(conf.low, na.rm=TRUE), max_conf_high = max(conf.high, na.rm=TRUE)) ggplot(data = data, aes(x = year, y = median, ymin = min_conf_low, ymax = max_conf_high)) + geom_path() + theme_bw()+ geom_ribbon(aes(ymax = max_conf_high, ymin = min_conf_low), alpha = 0.3, fill = "lightgrey") + geom_smooth(aes(y=median), color = "black") + labs(y="Raw correlation between GDP per capita (various measures) and extended Unified Democracy Score, per year") + geom_hline(yintercept = 0, linetype=2) + coord_cartesian(xlim=c(1850,2014))
Inequality data is from the Standardized Worldwide Income Inequality Database [@Solt2016; @Solt2009].
count_sequence_breaks <- function(seq, seq_step = 1) { first_diff <- c(seq_step, diff(seq)) - seq_step periods <- cumsum(abs(first_diff)) periods } data <- swiid_summary_5 %>% filter(country_name %in% c("Egypt","Tunisia")) world_ineq <- swiid_summary_5 %>% group_by(year,variable) %>% summarise(mean_value = mean(mean_value,na.rm=TRUE), se = sqrt(sum(se^2))/n()) middle_east_ineq <- swiid_summary_5 %>% filter(region %in% c("Northern Africa","Western Asia"), !(country_name %in% c("Georgia","Azerbaijan","Cyprus"))) %>% group_by(year,variable) %>% summarise(mean_value = mean(mean_value,na.rm=TRUE), se = sqrt(sum(se^2))/n()) world_ineq$country_name <- "World avg." middle_east_ineq$country_name <- "Middle East avg." data <- bind_rows(data, world_ineq, middle_east_ineq) %>% filter(variable == "gini_net") %>% group_by(country_name) %>% arrange(year) %>% mutate(period = paste(count_sequence_breaks(year), country_name)) %>% ungroup() ggplot(data = data %>% filter(country_name != "Tunisia"), aes(x=year, y = mean_value, color = country_name, fill = country_name, ymin = mean_value - 1.96*se, ymax = mean_value + 1.96*se, group = period)) + geom_path() + geom_point() + geom_ribbon(alpha=0.2) + labs(fill = "", color ="", y = "Net gini index\n(after taxes and transfers, higher values indicate more inequality)") + theme_bw() + theme(legend.position ="bottom") + geom_vline(xintercept = 2011, color = "red") + geom_text(x = 2011, y = 50, label = "2011 revolution", angle = 90, color = "black")
ggplot(data = data %>% filter(country_name != "Egypt"), aes(x=year, y = mean_value, color = forcats::fct_relevel(country_name, "Tunisia"), fill = forcats::fct_relevel(country_name, "Tunisia"), ymin = mean_value - 1.96*se, ymax = mean_value + 1.96*se, group = period)) + geom_point() + geom_path() + geom_ribbon(alpha=0.2) + labs(fill = "", color ="", y = "Net gini index\n(after taxes and transfers, higher values indicate more inequality)") + theme_bw() + theme(legend.position ="bottom") + geom_vline(xintercept = 2011, color = "red") + geom_text(x = 2011, y = 50, label = "2011 revolution", angle = 90, color = "black")
data <- swiid_summary_5 %>% filter(country_name %in% c("Venezuela")) latinamerica_ineq <- swiid_summary_5 %>% filter(region %in% c("Southern America","Central America")) %>% group_by(year, variable) %>% summarise(mean_value = mean(mean_value, na.rm=TRUE), se = sqrt(sum(se^2))/n()) latinamerica_ineq$country_name <- "Latin America avg." data <- bind_rows(data, world_ineq, latinamerica_ineq) %>% filter(variable == "gini_net") %>% group_by(country_name) %>% arrange(year) %>% mutate(period = paste(count_sequence_breaks(year), country_name)) %>% ungroup() ggplot(data = data %>% filter(country_name != "Egypt"), aes(x=year, y = mean_value, color = forcats::fct_relevel(country_name, "Venezuela"), fill = forcats::fct_relevel(country_name, "Venezuela"), ymin = mean_value - 1.96*se, ymax = mean_value + 1.96*se, group = period)) + geom_path() + geom_point() + geom_ribbon(alpha=0.2) + labs(fill = "", color ="", y = "Net gini index\n(after taxes and transfers, higher values indicate more inequality)") + theme_bw() + theme(legend.position ="bottom") + geom_vline(xintercept = 1997, color = "red") + geom_text(x = 1997, y = 50, label = "Chavez is elected", angle = 90, color = "black")
The inequality measure is the net gini index of income inequality (net means after taxes and transfers); it goes from 0 to 100, where higher numbers mean more inequality. Data on regimes is from @Kailitz2013. Inequality data from Solt [@Solt2009; @Solt2016]. The democracy data is from @Pemstein2010, extended by me [@Marquez2016]. The original figure used the package ggalt
, which is no longer compatible with ggplot2
; nothing changes if we use ggplot2::geom_density_2d
for the estimation.
data <- inner_join(swiid_summary_5, extended_uds %>% select(country_name, GWn, year, index) %>% rename(uds = index)) %>% inner_join(kailitz_yearly %>% select(-cown:-in_system) %>% mutate(democracy = grepl("Democracy",combined_regime)) %>% melt(measure.vars = c("personal", "communist", "military", "party", "monarchy", "electoral", "failure", "transition", "democracy")) %>% filter(value) %>% rename(regime = variable)) %>% filter(!is.na(regime), variable %in% c("gini_net")) %>% mutate(name = paste(country_name, year)) ggplot(data = data, aes(text = name, x = uds, y = mean_value, group = regime)) + geom_point(alpha = 0.2) + geom_density_2d() + theme_bw() + labs(y = "Gini index", x = "Unified democracy score (democracies = >0.5)", alpha = "Concentration of regimes", fill = "") + theme(legend.position = "bottom") + geom_vline(xintercept = 0.5, color = "red") + facet_wrap(~regime) + coord_cartesian(xlim=c(0,1))
Here's an interactive version (requires the plotly
package):
library(plotly) p <- ggplot(data = data %>% rename(gini_net = mean_value), aes(text = name, x = uds, y = gini_net, group = regime)) + geom_point(alpha = 0.2) + theme_bw() + labs(y = "Gini index", x = "Unified democracy score (democracies = >0.5)", alpha = "Concentration of regimes", fill = "") + theme(legend.position = "bottom") + geom_vline(xintercept = 0.5, color = "red") + facet_wrap(~regime) + coord_cartesian(xlim=c(0,1)) ggplotly(p)
We can use the measure of regime type from @MagaloniChuMin2013 instead:
data <- inner_join(swiid_summary_5, extended_uds %>% select(country_name, GWn, year, index) %>% rename(uds = index)) %>% inner_join(magaloni %>% select(country_name, GWn, year, regime_nr)) %>% left_join(kailitz_yearly %>% select(country_name, GWn, year, communist)) %>% mutate(regime = ifelse(communist, paste("Communist ", regime_nr), regime_nr)) %>% filter(!is.na(regime), variable %in% c("gini_net")) ggplot(data = data, aes(x = uds, y = mean_value, group = regime)) + geom_point(alpha = 0.2) + geom_density_2d() + theme_bw() + labs(y = "Gini index", x = "Unified democracy score (democracies = >0.5)", alpha = "Concentration of regimes", fill = "") + theme(legend.position = "bottom") + geom_vline(xintercept = 0.5, color = "red") + facet_wrap(~regime) + coord_cartesian(xlim=c(0,1))
Or from @WahmanTeorellHadenius2013:
data <- inner_join(swiid_summary_5, extended_uds %>% select(country_name, GWn, year, index) %>% rename(uds = index)) %>% inner_join(wahman_teorell %>% select(country_name, GWn, year, regime1ny)) %>% filter(!is.na(regime1ny)) %>% left_join(kailitz_yearly %>% select(country_name, GWn, year, communist)) %>% mutate(regime = ifelse(communist, paste("Communist ", regime1ny), as.character(regime1ny))) %>% filter(!is.na(regime), variable %in% c("gini_net")) ggplot(data = data, aes(x = uds, y = mean_value, group = regime)) + geom_point(alpha = 0.2) + geom_density_2d() + theme_bw() + labs(y = "Gini index", x = "Unified democracy score (democracies = >0.5)", alpha = "Concentration of regimes", fill = "") + theme(legend.position = "bottom") + geom_vline(xintercept = 0.5, color = "red") + facet_wrap(~regime) + coord_cartesian(xlim=c(0,1))
Or from @GeddesWrightFrantz2014:
data <- inner_join(swiid_summary_5, extended_uds %>% select(country_name, GWn, year, index) %>% rename(uds = index)) %>% inner_join(all_gwf %>% select(country_name, GWn, year, gwf_full_regimetype)) %>% filter(!is.na(gwf_full_regimetype)) %>% left_join(kailitz_yearly %>% select(country_name, GWn, year, communist)) %>% mutate(regime = ifelse(communist, paste("Communist ", gwf_full_regimetype), as.character(gwf_full_regimetype))) %>% filter(!is.na(regime), variable %in% c("gini_net")) ggplot(data = data, aes(x = uds, y = mean_value, group = regime)) + geom_point(alpha = 0.2) + geom_density_2d() + theme_bw() + labs(y = "Gini index", x = "Unified democracy score (democracies = >0.5)", alpha = "Concentration of regimes", fill = "") + theme(legend.position = "bottom") + geom_vline(xintercept = 0.5, color = "red") + facet_wrap(~regime) + coord_cartesian(xlim=c(0,1))
The correlation between inequality and democracy has varied accross countries.
data <- left_join(extended_uds, swiid_summary_5 %>% select(country_name, GWn, year, variable, mean_value)) %>% filter(variable == "gini_net") %>% group_by(variable, country_name) %>% filter(!is.na(mean_value), n() > 5) %>% summarise(index = list(index), mean_value = list(mean_value)) %>% mutate(cor_test = map2(index, mean_value, ~ tidy(cor.test(.x, .y)))) %>% unnest(cor_test) ggplot(data = data, aes(x = forcats::fct_reorder(country_name, estimate, na.rm =TRUE), y = estimate)) + geom_pointrange(aes(ymin = conf.low, ymax = conf.high)) + labs(x = "", y = "Estimated correlation", color = "Measure") + theme_bw() + theme(legend.position = "bottom") + guides(color = guide_legend(ncol=2)) + geom_hline(yintercept = 0, color = "red") + coord_flip()
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.