#### Paper title: Polls of fear? Electoral violence, incumbent strength, and voter turnout in Côte d'Ivoire
#### Purpose: Data management, descriptive statistics, main analysis, appendix analysis
#### Author: Sebastian van Baalen
#### Date: 2023-01-04
#### Read this first ####
# If the script contains errors or fails to run, compare the package version
# with the version listed in the run-file.
# Note that starting from section "Additional analyses and robustness tests",
# the script overwrites existing model objects for convenience.
# The following error message when calculating McFadden's Adjusted R2 is due to
# the error message prompted by using glm with family = binomial(link = logit)
# and disappears if using glm with family = quasibinomial instead. The results
# are however the same.
# Warning messages:
# 1: In eval(family$initialize) : non-integer #successes in a binomial glm!
# 2: In res["Tjur"] <- unname(diff(tapply(y.hat.resp, y, mean, na.rm = TRUE))) :
# number of items to replace is not a multiple of replacement length
#### Front matter ####
# Install packages
# Un-comment to install packages
#install.packages("here") # For using relative paths
#install.packages("ggplot2") # For making graphs and figures
#install.packages("tidyverse") # For working with tidy data
#install.packages("sf") # For working with spatial data
#install.packages("sandwich") # For working with robust standard errors
#install.packages("spdep") # For creating spatial weights matrices
#install.packages("lmtest") # For calculating robust standard errors
#install.packages("interactions") # For examining interaction effects
#install.packages("viridis") # For using the Viridis color scales
#install.packages("ggdist") # For visualizing distributions
#install.packages("MatchIt") # For matching
#install.packages("stargazer") # For exporting regression tables
#install.packages("DescTools") # For calculating McFadden's Adjusted R2
#install.packages("marginaleffects") # For calculating marginal effects
#install.packages("insight") # For calculating robust standard errors for marginal effects
#install.packages("ggtext") # For adding text to ggplot objects
#install.packages("interflex") # For interrogating interaction effects
# Load packages
library(here) # For using relative paths (must be loaded first)
## here() starts at /Users/sebva935/Documents/Datasets and scripts/Replication files/JPR 2022
library(ggplot2) # For making graphs and figures
library(tidyverse) # For working with tidy data
## ── Attaching packages
## ───────────────────────────────────────
## tidyverse 1.3.2 ──
## ✔ tibble 3.1.8 ✔ dplyr 1.0.10
## ✔ tidyr 1.2.1 ✔ stringr 1.4.1
## ✔ readr 2.1.3 ✔ forcats 0.5.2
## ✔ purrr 0.3.5
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
library(sf) # For working with spatial data
## Linking to GEOS 3.10.2, GDAL 3.4.2, PROJ 8.2.1; sf_use_s2() is TRUE
library(sandwich) # For working with robust standard errors
library(spdep) # For creating spatial weights matrices
## Loading required package: sp
## Loading required package: spData
## To access larger datasets in this package, install the spDataLarge
## package with: `install.packages('spDataLarge',
## repos='https://nowosad.github.io/drat/', type='source')`
library(lmtest) # For calculating robust standard errors
## Loading required package: zoo
##
## Attaching package: 'zoo'
##
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
library(interactions) # For examining interaction effects
library(viridis) # For using the Viridis color scales
## Loading required package: viridisLite
library(ggdist) # For visualizing distributions
library(MatchIt) # For matching
library(stargazer) # For For exporting regression tables
##
## Please cite as:
##
## Hlavac, Marek (2022). stargazer: Well-Formatted Regression and Summary Statistics Tables.
## R package version 5.2.3. https://CRAN.R-project.org/package=stargazer
library(DescTools) # For calculating McFadden's Adjusted R2
##
## Attaching package: 'DescTools'
##
## The following object is masked from 'package:ggdist':
##
## Mode
library(marginaleffects) # For calculating marginal effects
library(insight) # For calculating robust standard errors for marginal effects
library(ggtext) # For adding text to ggplot objects
library(interflex) # For interrogating interaction effects
## ## Syntax has changed since v.1.2.1.
##
## ## See http://bit.ly/interflex for more info.
## ## Comments and suggestions -> zyliu2020@uchicago.edu.
# Load election dataset
load("df.Rdata")
# Load electoral violence dataset
load("ev.Rdata")
# Load voting districts shapefile
shapefile <- st_read("shapefile.shp")
## Reading layer `shapefile' from data source
## `/Users/sebva935/Documents/Datasets and scripts/Replication files/JPR 2022/shapefile.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 205 features and 3 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -8.584147 ymin: 4.360553 xmax: -2.492309 ymax: 10.74565
## Geodetic CRS: WGS 84
#### Data management ####
##### Create electoral violence variables ####
# Merge election dataset with shapefile
df <- shapefile %>%
rename(Vote.District = Legislativ) %>%
left_join(df, by = "Vote.District")
# Make electoral violence dataset spatial to enable geo-processing
ev <- as.data.frame(ev) %>%
st_as_sf(coords = c("Longitude", "Latitude"), crs = 4326, remove = FALSE)
# Create electoral violence variables
ev <- ev %>%
mutate(
Electoral.Violence.Events.Opposition = case_when(
Actor1Side == 1 & EventDirection == 0 ~ 1,
Actor1Side == 1 & ViolenceInitiator == "0,1" ~ 1,
TRUE ~ 0
),
Electoral.Violence.Events.Incumbent = case_when(
Actor1Side == 0 & EventDirection == 0 ~ 1,
Actor1Side == 0 & ViolenceInitiator == "0,1" ~ 1,
Actor2Side == 0 & ViolenceInitiator == "0,2" ~ 1,
TRUE ~ 0
),
Electoral.Violence.Events.Casualties = case_when(
ParticipantDeaths > 0 | ParticipantInjuries > 0 ~ 1,
TRUE ~ 0
),
Electoral.Violence.Events.No.Casualties = case_when(
ParticipantDeaths == 0 & ParticipantInjuries == 0 ~ 1,
TRUE ~ 0
),
Electoral.Violence.Events.Clear = case_when(
Clarity == 1 ~ 1,
TRUE ~ 0
),
Timing = case_when(
Date <= "2020-10-31" ~ "Pre-election",
TRUE ~ "Post-election"
),
Electoral.Violence.Severity = ParticipantDeaths + ParticipantInjuries
)
# Subset datasets to enable geo-processing
ev_opposition <- ev %>% filter(Electoral.Violence.Events.Opposition == 1)
ev_incumbent <- ev %>% filter(Electoral.Violence.Events.Incumbent == 1)
ev_casualties <- ev %>% filter(Electoral.Violence.Events.Casualties == 1)
ev_no_casualties <- ev %>% filter(Electoral.Violence.Events.No.Casualties == 1)
ev_clear <- ev %>% filter(Electoral.Violence.Events.Clear == 1)
ev_pre <- ev %>% filter(Timing == "Pre-election")
ev_post <- ev %>% filter(Timing == "Post-election")
ev_severity <- ev %>% select(Electoral.Violence.Severity)
df_severity <- df %>% select(Vote.District)
ev_severity <- st_join(df_severity, ev_severity)
# Create electoral violence event count variables by counting points in polygon
df <- df %>%
mutate(
Electoral.Violence.Events = lengths(st_intersects(x = df, y = ev)),
Electoral.Violence.Events.Opposition = lengths(st_intersects(x = df, y = ev_opposition)),
Electoral.Violence.Events.Incumbent = lengths(st_intersects(x = df, y = ev_incumbent)),
Electoral.Violence.Events.Casualties = lengths(st_intersects(x = df, y = ev_casualties)),
Electoral.Violence.Events.Dummy = case_when(Electoral.Violence.Events > 0 ~ 1, TRUE ~ 0),
Electoral.Violence.Events.No.Casualties = lengths(st_intersects(x = df, y = ev_no_casualties)),
Electoral.Violence.Events.Clear = lengths(st_intersects(x = df, y = ev_clear )),
Pre.Electoral.Violence.Events = lengths(st_intersects(x = df, y = ev_pre)),
Post.Electoral.Violence.Events = lengths(st_intersects(x = df, y = ev_post))
)
# Sum number of victims by vote district
ev_severity <- ev_severity %>%
group_by(Vote.District) %>%
mutate(Electoral.Violence.Severity = sum(Electoral.Violence.Severity)) %>%
distinct(Vote.District, .keep_all = TRUE)
ev_severity$Electoral.Violence.Severity[is.na(ev_severity$Electoral.Violence.Severity)] <- 0
##### Create spatial lag variables ####
# Identify contiguous voting district neighbors
contig <- poly2nb(df)
# Create a spatial weights matrix (row-standardized)
spcontig <- nb2listw(contig, zero.policy = TRUE)
# Create spatially lagged electoral violence variables
df$Electoral.Violence.Events.Spatial.Lag <- lag.listw(spcontig, df$Electoral.Violence.Events)
##### Create incumbent strength variables ####
df <- df %>%
mutate(
RDR.Vote.Share.2010.Sq = RDR.Vote.Share.2010 ^ 2,
RDR.Margin.2010 = RDR.Vote.Share.2010 - Competitor.Vote.Share.2010,
RDR.Dominance.2010 = RDR.Vote.Share.2010 * RDR.Margin.2010
)
##### Remove superfluous dataframes ####
rm("contig", "ev_incumbent", "ev_opposition", "spcontig", "ev_casualties", "ev_clear", "ev_pre", "ev_post", "df_severity", "ev_no_casualties")
#### Descriptive statistics ####
##### Make electoral violence and voter turnout map ####
# Make map
ggplot(data = df) +
geom_sf(
aes(
fill = Voter.Turnout.2021
),
color = "white",
size = 0.1,
) +
coord_sf(
xlim = c(-9, -2),
ylim = c(4, 11),
expand = FALSE
) +
scale_fill_viridis(
name = "Voter turnout",
option = "viridis",
discrete = FALSE,
begin = 0.1,
end = 0.9,
direction = -1,
na.value = "white",
limits = c(0, 1)
) +
geom_count(
data = ev,
aes(
x = Longitude,
y = Latitude
),
shape = 21,
color = "black",
fill = "white",
alpha = 0.6
) +
scale_size(
name = "Event count",
range = c(3, 14)
) +
annotate(
"text",
x = -3.55,
y = 9.1,
label = "Bouna\nNational\nPark",
size = 3.5,
lineheight = 1,
hjust = "center"
) +
theme_void() +
theme(
plot.title = element_text(size = 16, face = "bold", hjust = 0, margin = margin (t = 0, r = 0, b = 10, l = 0)),
plot.caption = element_text(hjust = 1, size = 8, lineheight = 0.5, margin = margin (t = 20, r = 0, b = 20, l = 0)),
legend.position = "right",
plot.subtitle = element_markdown(size = 12, hjust = 0, lineheight = 1.2, margin = margin (t = 0, r = 0, b = 20, l = 0))
)

ggsave("figure_5.jpg", width = 10, height = 8.9, dpi = 600)
##### Make electoral violence and incumbent strength map ####
# Make map
ggplot(data = df) +
geom_sf(
aes(
fill = RDR.Vote.Share.2010
),
color = "white",
size = 0.1,
) +
coord_sf(
xlim = c(-9, -2),
ylim = c(4, 11),
expand = FALSE
) +
scale_fill_viridis(
name = "Incumbent vote share",
option = "viridis",
discrete = FALSE,
begin = 0.1,
end = 0.9,
direction = -1,
na.value = "white",
limits = c(0, 1)
) +
geom_count(
data = ev,
aes(
x = Longitude,
y = Latitude
),
shape = 21,
color = "black",
fill = "white",
alpha = 0.6
) +
scale_size(
name = "Event count",
range = c(3, 14)
) +
annotate(
"text",
x = -3.55,
y = 9.1,
label = "Bouna\nNational\nPark",
size = 3.5,
lineheight = 1,
hjust = "center"
) +
theme_void() +
theme(
plot.title = element_text(size = 16, face = "bold", hjust = 0, margin = margin (t = 0, r = 0, b = 10, l = 0)),
plot.caption = element_text(hjust = 1, size = 8, lineheight = 0.5, margin = margin (t = 20, r = 0, b = 20, l = 0)),
legend.position = "right",
plot.subtitle = element_markdown(size = 12, hjust = 0, lineheight = 1.2, margin = margin (t = 0, r = 0, b = 20, l = 0))
)

ggsave("figure_6.jpg", width = 10, height = 8.9, dpi = 600)
##### Make electoral violence and incumbent strength 2021 map ####
# Make map
ggplot(data = df) +
geom_sf(
aes(
fill = RHDP.Vote.Share.2021
),
color = "white",
size = 0.1,
) +
coord_sf(
xlim = c(-9, -2),
ylim = c(4, 11),
expand = FALSE
) +
scale_fill_viridis(
name = "Incumbent vote share",
option = "viridis",
discrete = FALSE,
begin = 0.1,
end = 0.8,
direction = -1,
na.value = "white",
limits = c(0, 1)
) +
geom_count(
data = ev,
aes(
x = Longitude,
y = Latitude
),
shape = 21,
color = "black",
fill = "white",
alpha = 0.6
) +
scale_size(
name = "Event count",
range = c(3, 14)
) +
annotate(
"text",
x = -3.55,
y = 9.1,
label = "Bouna\nNational\nPark",
size = 3.5,
lineheight = 1,
hjust = "center"
) +
theme_void() +
theme(
plot.title = element_text(size = 16, face = "bold", hjust = 0, margin = margin (t = 0, r = 0, b = 10, l = 0)),
plot.caption = element_text(hjust = 1, size = 8, lineheight = 0.5, margin = margin (t = 20, r = 0, b = 20, l = 0)),
legend.position = "right",
plot.subtitle = element_markdown(size = 12, hjust = 0, lineheight = 1.2, margin = margin (t = 0, r = 0, b = 20, l = 0))
)

ggsave("figure_a3.jpg", width = 10, height = 8.9, dpi = 600)
##### Make timeline of electoral violence events ####
ev %>%
mutate(
Events = 1,
Date = as.Date(Date, format = "%Y-%m-%d")
) %>%
complete(
Date = seq.Date(min(as.Date("2020-07-31")), max(as.Date("2021-03-06")), by = "day"),
fill = list(Events = 0, ParticipantDeaths = 0, ParticipantInjuries = 0)
) %>%
group_by(Date) %>%
mutate(
Events = sum(Events),
Victims = ParticipantDeaths + ParticipantInjuries,
) %>%
distinct(Date, .keep_all = TRUE) %>%
ggplot() +
geom_area(
aes(
x = Date,
y = Events
),
fill = "#482878FF",
alpha = 0.8
) +
geom_vline(xintercept = as.numeric(as.Date("2020-08-06")), linetype = "dashed") +
annotate(
"label",
x = as.Date("2020-08-06"),
y = 80,
label = "Ouattara \n announces his \n third-term bid",
size = 4,
lineheight = 1,
hjust = "center",
color = "black",
fill = "white"
) +
geom_vline(xintercept = as.numeric(as.Date("2020-09-20")), linetype = "dashed") +
annotate(
"label",
x = as.Date("2020-09-20"),
y = 30,
label = "Opposition calls \n for a nationwide \n civil disobedience \n campaign",
size = 4,
lineheight = 1,
hjust = "center",
color = "black",
fill = "white"
) +
geom_vline(xintercept = as.numeric(as.Date("2020-10-15")), linetype = "dashed") +
annotate(
"label",
x = as.Date("2020-10-15"),
y = 50,
label = "Opposition announces \n an election boycott",
size = 4,
lineheight = 1,
hjust = "center",
color = "black",
fill = "white"
) +
geom_vline(xintercept = as.numeric(as.Date("2020-10-31")), linetype = "dashed") +
annotate(
"label",
x = as.Date("2020-10-31"),
y = 100,
label = "Presidential \n election",
size = 4,
lineheight = 1,
hjust = "center",
color = "black",
fill = "white"
) +
geom_vline(xintercept = as.numeric(as.Date("2021-03-06")), linetype = "dashed") +
annotate(
"label",
x = as.Date("2021-03-06"),
y = 60,
label = "Legislative \n election",
size = 4,
lineheight = 1,
hjust = "center",
color = "black",
fill = "white"
) +
scale_y_continuous(
breaks = seq(0, 100, by = 10)
) +
scale_x_date(
date_breaks = "1 month",
date_labels = "%B %Y"
) +
labs(
x = NULL,
y = "Number of electoral violence events"
) +
theme_bw() +
theme(
axis.title.y = element_text(margin = margin (t = 0, r = 10, b = 0, l = 0), size = 16),
axis.title.x = element_text(margin = margin (t = 10, r = 0, b = 0, l = 0), size = 16),
axis.text.y = element_text(size = 14),
axis.text.x = element_text(size = 12)
)

ggsave("figure_4.jpg", width = 14, height = 8.9, dpi = 600)
# Transform into normal data frame
df <- df %>% as.data.frame
# Add severity variable to data frame
df <- left_join(df, ev_severity, by = "Vote.District")
# Remove severity data frame
rm("ev_severity")
##### Create descriptive statistics table ####
df_descriptive <- df %>%
select(
Voter.Turnout.2021,
Electoral.Violence.Events,
Electoral.Violence.Events.Opposition,
Electoral.Violence.Events.Incumbent,
Electoral.Violence.Events.Casualties,
Electoral.Violence.Events.Spatial.Lag,
RDR.Vote.Share.2010,
Electoral.Violence.Events.2011,
Number.of.Seats.2021,
Voter.Turnout.2016,
Poverty.Ratio,
Population.2014.Logged
)
stargazer(
df_descriptive,
covariate.labels = c(
"Voter turnout",
"Electoral violence (all)",
"Opposition violence",
"Incumbent violence",
"Severe violence",
"Electoral violence (spatial lag)",
"Incumbent strength",
"Electoral violence (2011)",
"Number of seats",
"Voter turnout (2016)",
"Poverty ratio",
"Logged population size"
),
title = "Descriptive statistics",
digits = 2,
omit.summary.stat = c("p25", "p75"),
type = "text",
out = "table_a1",
median = TRUE
)
##
## Descriptive statistics
## =====================================================================
## Statistic N Mean St. Dev. Min Median Max
## ---------------------------------------------------------------------
## Voter turnout 205 0.48 0.16 0.14 0.46 0.99
## Electoral violence (all) 205 1.56 2.70 0 0 18
## Opposition violence 205 0.56 1.34 0 0 10
## Incumbent violence 205 0.28 0.88 0 0 7
## Severe violence 205 0.38 1.11 0 0 11
## Electoral violence (spatial lag) 205 1.74 1.80 0.00 1.29 12.00
## Incumbent strength 205 0.37 0.29 0.04 0.23 0.94
## Electoral violence (2011) 205 0.54 2.91 0 0 37
## Number of seats 205 1.24 0.67 1 1 6
## Voter turnout (2016) 205 0.45 0.18 0.11 0.44 0.96
## Poverty ratio 205 0.53 0.19 0.00 0.54 0.99
## Logged population size 205 10.39 1.12 7.85 10.25 13.88
## ---------------------------------------------------------------------
rm(df_descriptive)
#### Main analysis ####
##### Model 1: Bivariate regression of electoral violence and voter turnout ####
# Specify model 1
model1 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model1, vcov = vcovHC(model1, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.049501 0.053306 0.9286 0.3531
## Electoral.Violence.Events -0.099410 0.020623 -4.8203 1.433e-06 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##### Model 2: Multivariate regression of electoral violence and voter turnout ####
# Specify model 2
model2 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events +
RDR.Vote.Share.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model2, vcov = vcovHC(model2, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.12511099 0.64201031 0.1949 0.845492
## Electoral.Violence.Events -0.00985772 0.00862335 -1.1431 0.252979
## RDR.Vote.Share.2010 0.42660778 0.13766400 3.0989 0.001942
## Electoral.Violence.Events.Spatial.Lag 0.00046143 0.01273773 0.0362 0.971102
## Electoral.Violence.Events.2011 -0.01391317 0.00559476 -2.4868 0.012889
## Number.of.Seats.2021 0.02597102 0.05991440 0.4335 0.664674
## Voter.Turnout.2016 1.91900118 0.42067869 4.5617 5.075e-06
## Poverty.Ratio 0.22430430 0.13779195 1.6278 0.103557
## Population.2014.Logged -0.13407665 0.05097300 -2.6303 0.008530
##
## (Intercept)
## Electoral.Violence.Events
## RDR.Vote.Share.2010 **
## Electoral.Violence.Events.Spatial.Lag
## Electoral.Violence.Events.2011 *
## Number.of.Seats.2021
## Voter.Turnout.2016 ***
## Poverty.Ratio
## Population.2014.Logged **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##### Model 3: Multivariate regression of electoral violence and voter turnout with interaction ####
# Specify model 3
model3 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events * RDR.Vote.Share.2010 +
RDR.Vote.Share.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model3, vcov = vcovHC(model3, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value
## (Intercept) -0.0039912 0.5449570 -0.0073
## Electoral.Violence.Events 0.0440658 0.0225737 1.9521
## RDR.Vote.Share.2010 0.5185501 0.1449603 3.5772
## Electoral.Violence.Events.Spatial.Lag 0.0044690 0.0124306 0.3595
## Electoral.Violence.Events.2011 -0.0102528 0.0073618 -1.3927
## Number.of.Seats.2021 0.0559194 0.0674814 0.8287
## Voter.Turnout.2016 1.8544361 0.3873199 4.7879
## Poverty.Ratio 0.2147157 0.1332503 1.6114
## Population.2014.Logged -0.1239489 0.0425629 -2.9121
## Electoral.Violence.Events:RDR.Vote.Share.2010 -0.3424658 0.1450439 -2.3611
## Pr(>|z|)
## (Intercept) 0.9941564
## Electoral.Violence.Events 0.0509281 .
## RDR.Vote.Share.2010 0.0003473 ***
## Electoral.Violence.Events.Spatial.Lag 0.7192106
## Electoral.Violence.Events.2011 0.1637113
## Number.of.Seats.2021 0.4072947
## Voter.Turnout.2016 1.686e-06 ***
## Poverty.Ratio 0.1070989
## Population.2014.Logged 0.0035896 **
## Electoral.Violence.Events:RDR.Vote.Share.2010 0.0182199 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Calculate predicted values
predictions(
model3,
newdata = datagrid(
RDR.Vote.Share.2010 = c(0.1, 0.7),
Electoral.Violence.Events = c(0, 3)
),
vcov = sandwich::vcovHC(model3, type = "HC")
)
## rowid type predicted std.error statistic p.value conf.low
## 1 1 response 0.4464942 0.008673666 51.476985 0.000000e+00 0.4295631
## 2 2 response 0.4537852 0.008425075 53.861266 0.000000e+00 0.4373291
## 3 3 response 0.5240524 0.017328763 30.241769 6.693970e-201 0.4900298
## 4 4 response 0.3797295 0.052343520 7.254565 4.029536e-13 0.2836832
## conf.high Voter.Turnout.2021 Electoral.Violence.Events.Spatial.Lag
## 1 0.4635503 0.4750257 1.744299
## 2 0.4703429 0.4750257 1.744299
## 3 0.5578533 0.4750257 1.744299
## 4 0.4862212 0.4750257 1.744299
## Electoral.Violence.Events.2011 Number.of.Seats.2021 Voter.Turnout.2016
## 1 1 1.243902 0.454901
## 2 1 1.243902 0.454901
## 3 1 1.243902 0.454901
## 4 1 1.243902 0.454901
## Poverty.Ratio Population.2014.Logged RDR.Vote.Share.2010
## 1 0.5334743 10.3909 0.1
## 2 0.5334743 10.3909 0.1
## 3 0.5334743 10.3909 0.7
## 4 0.5334743 10.3909 0.7
## Electoral.Violence.Events
## 1 0
## 2 3
## 3 0
## 4 3
# Calculate change in standard deviation
(0.53-0.38)/sd(df$Voter.Turnout.2021)
## [1] 0.9532803
# Calculate the Johnson-Neyman interval (regions of significance)
sim_slopes(
model3,
pred = Electoral.Violence.Events,
modx = RDR.Vote.Share.2010,
robust = "HC",
centered = "all"
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## JOHNSON-NEYMAN INTERVAL
##
## When RDR.Vote.Share.2010 is OUTSIDE the interval [-0.01, 0.20], the slope
## of Electoral.Violence.Events is p < .05.
##
## Note: The range of observed values of RDR.Vote.Share.2010 is [0.04, 0.94]
##
## SIMPLE SLOPES ANALYSIS
##
## Slope of Electoral.Violence.Events when RDR.Vote.Share.2010 = 0.07852611 (- 1 SD):
##
## Est. S.E. z val. p
## ------ ------ -------- ------
## 0.02 0.01 1.33 0.19
##
## Slope of Electoral.Violence.Events when RDR.Vote.Share.2010 = 0.37323130 (Mean):
##
## Est. S.E. z val. p
## ------- ------ -------- ------
## -0.08 0.03 -2.42 0.02
##
## Slope of Electoral.Violence.Events when RDR.Vote.Share.2010 = 0.66793648 (+ 1 SD):
##
## Est. S.E. z val. p
## ------- ------ -------- ------
## -0.18 0.08 -2.40 0.02
# Calculate the share of observations that fall within the Johnson-Neyman interval
length(df$RDR.Vote.Share.2010[df$RDR.Vote.Share.2010 > 0.2])/205
## [1] 0.6487805
###### Make predicted values plot ####
# Calculate mean +/- standard deviation of incumbent strength
mean(df$RDR.Vote.Share.2010)
## [1] 0.3732313
mean(df$RDR.Vote.Share.2010) - sd(df$RDR.Vote.Share.2010)
## [1] 0.07852611
mean(df$RDR.Vote.Share.2010) + sd(df$RDR.Vote.Share.2010)
## [1] 0.6679365
# Calculate adjusted predictions
predicted3 <- predictions(
model3,
newdata = datagrid(
RDR.Vote.Share.2010 = c(0.08, 0.67),
Electoral.Violence.Events = c(0:15)
),
vcov = sandwich::vcovHC(model3, type = "HC")
)
# Plot predicted values
ggplot(data = predicted3) +
geom_line(aes(x = Electoral.Violence.Events, y = predicted, color = as.factor(RDR.Vote.Share.2010))) +
geom_ribbon(aes(x = Electoral.Violence.Events, ymin = conf.low, ymax = conf.high, fill = as.factor(RDR.Vote.Share.2010)), alpha = 0.2) +
scale_color_viridis(
name = "Incumbent strength",
labels = c("Low (mean - 1 SD)", "High (mean + 1 SD)"),
discrete = TRUE,
begin = 0.1,
end = 0.9
) +
scale_fill_viridis(discrete = TRUE) +
scale_y_continuous(
breaks = seq(0, 1, 0.25),
minor_breaks = FALSE,
labels = scales::percent_format(accuracy = 5L),
limits = c(0, 1)
) +
scale_x_continuous(
breaks = seq(0, 18, 4),
minor_breaks = FALSE
) +
guides(fill = "none") +
labs(
y = "Predicted voter turnout rate",
x = "Number of electoral violence events"
) +
theme_bw() +
theme(
plot.margin = unit(c(1,1,1,1), "cm"),
axis.title.y = element_text(margin = margin (t = 0, r = 10, b = 0, l = 0), size = 14),
axis.title.x = element_text(margin = margin (t = 10, r = 0, b = 0, l = 0), size = 14),
axis.text.x = element_text(size = 12),
axis.text.y = element_text(size = 12),
legend.position = "bottom"
)

ggsave("figure_7_panel_left.jpg", height = 15, width = 17, units = "cm", dpi = 600)
###### Make marginal effects plot ####
# Calculate marginal effects for different levels of incumbent strength
marginal3 <- plot_cme(
model3, effect = "Electoral.Violence.Events",
condition = "RDR.Vote.Share.2010",
vcov = sandwich::vcovHC(model3, type = "HC"),
draw = FALSE
)
# Define transform value for y-scale
coeff <- 0.4
# Make conditional effects plot with super-imposed distribution of incumbent strength
ggplot() +
geom_histogram(data = df, aes(x = RDR.Vote.Share.2010, y = (..count..) * 0.01), fill = alpha("#482878FF", 0.8)) +
geom_line(data = marginal3, aes(x = condition1, y = comparison + coeff)) +
geom_ribbon(data = marginal3, aes(x = condition1, ymin = conf.low + coeff, ymax = conf.high + coeff), fill = "#482878FF", alpha = 0.4) +
scale_y_continuous(
breaks = seq(0, 0.8, 0.1),
labels = seq(-0.4, 0.4, 0.1),
sec.axis = sec_axis(
trans = ~. * 100,
name = "Number of observations",
breaks = seq(0, 50, 10)
)
) +
scale_x_continuous(breaks = seq(0, 1, 0.2), limits = c(0, 1), labels = scales::percent) +
geom_hline(yintercept = 0.4, size = 0.5, linetype = 2) +
geom_vline(xintercept = 0.2, size = 0.5, linetype = 2) +
labs(
y = "Marginal effect of electoral violence on turnout",
x = "Incumbent vote share",
title = NULL
) +
theme_bw() +
theme(
plot.margin = unit(c(1,1,1,1), "cm"),
axis.title.y = element_text(margin = margin (t = 0, r = 10, b = 0, l = 0), size = 14),
axis.title.x = element_text(margin = margin (t = 10, r = 0, b = 0, l = 0), size = 14),
axis.title.y.right = element_text(margin = margin (t = 0, r = 0, b = 0, l = 10), size = 14),
axis.text.x = element_text(size = 12),
axis.text.y = element_text(size = 12),
legend.position = "bottom"
)
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## Warning: The dot-dot notation (`..count..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(count)` instead.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 2 rows containing missing values (`geom_bar()`).

ggsave("figure_7_panel_right.jpg", height = 15, width = 17, units = "cm", dpi = 600)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 2 rows containing missing values (`geom_bar()`).
##### Model 4: Multivariate regression of opposition-initiated and incumbent-initiated electoral violence and voter turnout ####
# Specify model 4
model4 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events.Opposition * RDR.Vote.Share.2010 +
Electoral.Violence.Events.Incumbent * RDR.Vote.Share.2010 +
RDR.Vote.Share.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model4, vcov = vcovHC(model4, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error
## (Intercept) -0.0701031 0.5255508
## Electoral.Violence.Events.Opposition 0.1277928 0.0557912
## RDR.Vote.Share.2010 0.5000196 0.1408343
## Electoral.Violence.Events.Incumbent -0.0941066 0.0696459
## Electoral.Violence.Events.Spatial.Lag -0.0021528 0.0132400
## Electoral.Violence.Events.2011 -0.0070820 0.0070134
## Number.of.Seats.2021 0.0377626 0.0607783
## Voter.Turnout.2016 1.9496112 0.3683385
## Poverty.Ratio 0.2150249 0.1373543
## Population.2014.Logged -0.1193817 0.0402047
## Electoral.Violence.Events.Opposition:RDR.Vote.Share.2010 -0.7258548 0.3147024
## RDR.Vote.Share.2010:Electoral.Violence.Events.Incumbent 0.2423050 0.3859184
## z value Pr(>|z|)
## (Intercept) -0.1334 0.8938852
## Electoral.Violence.Events.Opposition 2.2906 0.0219891 *
## RDR.Vote.Share.2010 3.5504 0.0003846 ***
## Electoral.Violence.Events.Incumbent -1.3512 0.1766269
## Electoral.Violence.Events.Spatial.Lag -0.1626 0.8708363
## Electoral.Violence.Events.2011 -1.0098 0.3125999
## Number.of.Seats.2021 0.6213 0.5343914
## Voter.Turnout.2016 5.2930 1.203e-07 ***
## Poverty.Ratio 1.5655 0.1174712
## Population.2014.Logged -2.9693 0.0029843 **
## Electoral.Violence.Events.Opposition:RDR.Vote.Share.2010 -2.3065 0.0210838 *
## RDR.Vote.Share.2010:Electoral.Violence.Events.Incumbent 0.6279 0.5300918
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##### Model 5: Multivariate regression of electoral violence resulting in casualties ####
# Specify model 5
model5 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events.Casualties * RDR.Vote.Share.2010 +
RDR.Vote.Share.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model5, vcov = vcovHC(model5, type = "HC"))
##
## z test of coefficients:
##
## Estimate
## (Intercept) 0.07400297
## Electoral.Violence.Events.Casualties 0.05228294
## RDR.Vote.Share.2010 0.45988299
## Electoral.Violence.Events.Spatial.Lag -0.00010904
## Electoral.Violence.Events.2011 -0.01679321
## Number.of.Seats.2021 0.04400033
## Voter.Turnout.2016 1.92658111
## Poverty.Ratio 0.20986455
## Population.2014.Logged -0.13195356
## Electoral.Violence.Events.Casualties:RDR.Vote.Share.2010 -0.51966592
## Std. Error z value
## (Intercept) 0.64185391 0.1153
## Electoral.Violence.Events.Casualties 0.02069790 2.5260
## RDR.Vote.Share.2010 0.13906981 3.3068
## Electoral.Violence.Events.Spatial.Lag 0.01241112 -0.0088
## Electoral.Violence.Events.2011 0.00621297 -2.7029
## Number.of.Seats.2021 0.06254376 0.7035
## Voter.Turnout.2016 0.40903484 4.7101
## Poverty.Ratio 0.13696476 1.5323
## Population.2014.Logged 0.05144377 -2.5650
## Electoral.Violence.Events.Casualties:RDR.Vote.Share.2010 0.19059292 -2.7266
## Pr(>|z|)
## (Intercept) 0.9082108
## Electoral.Violence.Events.Casualties 0.0115369 *
## RDR.Vote.Share.2010 0.0009435 ***
## Electoral.Violence.Events.Spatial.Lag 0.9929899
## Electoral.Violence.Events.2011 0.0068732 **
## Number.of.Seats.2021 0.4817363
## Voter.Turnout.2016 2.476e-06 ***
## Poverty.Ratio 0.1254602
## Population.2014.Logged 0.0103174 *
## Electoral.Violence.Events.Casualties:RDR.Vote.Share.2010 0.0063995 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##### Make regression table ####
# Create lists of robust standard errors
robust_se1 <- sqrt(diag(vcovHC(model1, type = "HC")))
robust_se2 <- sqrt(diag(vcovHC(model2, type = "HC")))
robust_se3 <- sqrt(diag(vcovHC(model3, type = "HC")))
robust_se4 <- sqrt(diag(vcovHC(model4, type = "HC")))
robust_se5 <- sqrt(diag(vcovHC(model5, type = "HC")))
# Create lists of McFadden's Adjusted R2
mcfadden1 <- format(round(PseudoR2(model1, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in res["Tjur"] <- unname(diff(tapply(y.hat.resp, y, mean, na.rm =
## TRUE))): number of items to replace is not a multiple of replacement length
mcfadden2 <- format(round(PseudoR2(model2, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden3 <- format(round(PseudoR2(model3, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden4 <- format(round(PseudoR2(model4, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden5 <- format(round(PseudoR2(model5, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
# Make regression table
stargazer(
model1,
model2,
model3,
model4,
model5,
title = "Fractional regression of voter turnout and electoral violence",
label = "tab:reg",
align = FALSE,
column.sep.width = "5pt",
no.space = TRUE,
omit.stat = c("LL", "ser", "f"),
se = list(robust_se1, robust_se2, robust_se3, robust_se4, robust_se5),
dep.var.labels = "Voter turnout",
digits = 2,
single.row = TRUE,
omit.table.layout = "ld",
order = c(1,12,2,13,5,14,3,15,4,6,7,8,9,10,11),
covariate.labels = c(
"All violence",
"All violence x Incumbent strength",
"Opposition violence",
"Opposition violence x Incumbent strength",
"Incumbent violence",
"Incumbent violence x Incumbent strength",
"Severe violence",
"Severe violence x Incumbent strength",
"Incumbent strength",
"Electoral violence (spatial lag)",
"Past electoral violence",
"Number of seats",
"Past voter turnout",
"Poverty ratio",
"Logged population size"
),
add.lines = list(c("McFadden's Adjusted R2", mcfadden1, mcfadden2, mcfadden3, mcfadden4, mcfadden5)),
notes.append = FALSE,
star.cutoffs = c(.1, .05, .01),
type = "text",
out = "table_I"
)
##
## Fractional regression of voter turnout and electoral violence
## ========================================================================================================================
## (1) (2) (3) (4) (5)
## ------------------------------------------------------------------------------------------------------------------------
## All violence -0.10*** (0.02) -0.01 (0.01) 0.04* (0.02)
## All violence x Incumbent strength -0.34** (0.15)
## Opposition violence 0.13** (0.06)
## Opposition violence x Incumbent strength -0.73** (0.31)
## Incumbent violence -0.09 (0.07)
## Incumbent violence x Incumbent strength 0.24 (0.39)
## Severe violence 0.05** (0.02)
## Severe violence x Incumbent strength -0.52*** (0.19)
## Incumbent strength 0.43*** (0.14) 0.52*** (0.14) 0.50*** (0.14) 0.46*** (0.14)
## Electoral violence (spatial lag) 0.0005 (0.01) 0.004 (0.01) -0.002 (0.01) -0.0001 (0.01)
## Past electoral violence -0.01** (0.01) -0.01 (0.01) -0.01 (0.01) -0.02*** (0.01)
## Number of seats 0.03 (0.06) 0.06 (0.07) 0.04 (0.06) 0.04 (0.06)
## Past voter turnout 1.92*** (0.42) 1.85*** (0.39) 1.95*** (0.37) 1.93*** (0.41)
## Poverty ratio 0.22 (0.14) 0.21 (0.13) 0.22 (0.14) 0.21 (0.14)
## Logged population size -0.13*** (0.05) -0.12*** (0.04) -0.12*** (0.04) -0.13** (0.05)
## Constant 0.05 (0.05) 0.13 (0.64) -0.004 (0.54) -0.07 (0.53) 0.07 (0.64)
## ------------------------------------------------------------------------------------------------------------------------
## McFadden's Adjusted R2 0.04 0.17 0.17 0.15 0.16
## Observations 205 205 205 205 205
## Akaike Inf. Crit. 268.73 232.34 232.78 236.08 234.15
## ========================================================================================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
#### Additional analyses and robustness tests ####
#### Matching ####
# Create binary electoral violence variable to match on
df <- df %>% mutate(Electoral.Violence.Events.Dummy = case_when(Electoral.Violence.Events > 0 ~ 1, TRUE ~ 0))
# Matching using Coarsened Exact Matching (CEM)
match.it <- matchit(
Electoral.Violence.Events.Dummy
~ RDR.Vote.Share.2010
+ Electoral.Violence.Events.Spatial.Lag,
data = df,
method = "cem"
)
# Show matching diagnostics (Table A2)
summary(match.it)
##
## Call:
## matchit(formula = Electoral.Violence.Events.Dummy ~ RDR.Vote.Share.2010 +
## Electoral.Violence.Events.Spatial.Lag, data = df, method = "cem")
##
## Summary of Balance for All Data:
## Means Treated Means Control
## RDR.Vote.Share.2010 0.2153 0.5150
## Electoral.Violence.Events.Spatial.Lag 2.4900 1.0746
## Std. Mean Diff. Var. Ratio eCDF Mean
## RDR.Vote.Share.2010 -1.9781 0.2248 0.2718
## Electoral.Violence.Events.Spatial.Lag 0.7635 1.6180 0.2648
## eCDF Max
## RDR.Vote.Share.2010 0.4739
## Electoral.Violence.Events.Spatial.Lag 0.4988
##
## Summary of Balance for Matched Data:
## Means Treated Means Control
## RDR.Vote.Share.2010 0.2060 0.2128
## Electoral.Violence.Events.Spatial.Lag 2.0894 2.1571
## Std. Mean Diff. Var. Ratio eCDF Mean
## RDR.Vote.Share.2010 -0.0451 1.0534 0.0263
## Electoral.Violence.Events.Spatial.Lag -0.0365 0.8648 0.0391
## eCDF Max Std. Pair Dist.
## RDR.Vote.Share.2010 0.1213 0.2112
## Electoral.Violence.Events.Spatial.Lag 0.0993 0.2513
##
## Sample Sizes:
## Control Treated
## All 108. 97
## Matched (ESS) 35.28 82
## Matched 83. 82
## Unmatched 25. 15
## Discarded 0. 0
summary(
match.it,
addlvariables = ~ Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df
)
##
## Call:
## matchit(formula = Electoral.Violence.Events.Dummy ~ RDR.Vote.Share.2010 +
## Electoral.Violence.Events.Spatial.Lag, data = df, method = "cem")
##
## Summary of Balance for All Data:
## Means Treated Means Control
## RDR.Vote.Share.2010 0.2153 0.5150
## Electoral.Violence.Events.Spatial.Lag 2.4900 1.0746
## Electoral.Violence.Events.2011 0.8557 0.2500
## Number.of.Seats.2021 1.3299 1.1667
## Voter.Turnout.2016 0.3788 0.5232
## Poverty.Ratio 0.4733 0.5876
## Population.2014.Logged 10.7882 10.0341
## Std. Mean Diff. Var. Ratio eCDF Mean
## RDR.Vote.Share.2010 -1.9781 0.2248 0.2718
## Electoral.Violence.Events.Spatial.Lag 0.7635 1.6180 0.2648
## Electoral.Violence.Events.2011 0.1565 5.8441 0.0473
## Number.of.Seats.2021 0.2274 1.3441 0.0349
## Voter.Turnout.2016 -0.9501 0.7688 0.2391
## Poverty.Ratio -0.6275 1.1009 0.1809
## Population.2014.Logged 0.6903 1.1566 0.1957
## eCDF Max
## RDR.Vote.Share.2010 0.4739
## Electoral.Violence.Events.Spatial.Lag 0.4988
## Electoral.Violence.Events.2011 0.1527
## Number.of.Seats.2021 0.1559
## Voter.Turnout.2016 0.4049
## Poverty.Ratio 0.3244
## Population.2014.Logged 0.3065
##
## Summary of Balance for Matched Data:
## Means Treated Means Control
## RDR.Vote.Share.2010 0.2060 0.2128
## Electoral.Violence.Events.Spatial.Lag 2.0894 2.1571
## Electoral.Violence.Events.2011 0.9268 0.1190
## Number.of.Seats.2021 1.3171 1.0762
## Voter.Turnout.2016 0.3834 0.4162
## Poverty.Ratio 0.4703 0.5780
## Population.2014.Logged 10.7989 10.2138
## Std. Mean Diff. Var. Ratio eCDF Mean
## RDR.Vote.Share.2010 -0.0451 1.0534 0.0263
## Electoral.Violence.Events.Spatial.Lag -0.0365 0.8648 0.0391
## Electoral.Violence.Events.2011 0.2087 42.9571 0.0537
## Number.of.Seats.2021 0.3357 4.3525 0.0460
## Voter.Turnout.2016 -0.2162 1.4924 0.0727
## Poverty.Ratio -0.5912 0.8601 0.1797
## Population.2014.Logged 0.5355 1.2583 0.1434
## eCDF Max Std. Pair Dist.
## RDR.Vote.Share.2010 0.1213 0.2112
## Electoral.Violence.Events.Spatial.Lag 0.0993 0.2513
## Electoral.Violence.Events.2011 0.1737 0.2836
## Number.of.Seats.2021 0.1928 0.4009
## Voter.Turnout.2016 0.1795 0.9931
## Poverty.Ratio 0.3310 1.2165
## Population.2014.Logged 0.2716 1.0840
##
## Sample Sizes:
## Control Treated
## All 108. 97
## Matched (ESS) 35.28 82
## Matched 83. 82
## Unmatched 25. 15
## Discarded 0. 0
# Create new dataset based on the CEM
df_matched <- match.data(match.it)
##### Model 1: Bivariate regression of electoral violence and voter turnout ####
# Specify Model 1
model1 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events.Dummy,
data = df_matched,
family = binomial(link = logit),
weights = weights
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model1, vcov = vcovHC(model1, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.208823 0.065175 -3.2040 0.001355 **
## Electoral.Violence.Events.Dummy -0.209086 0.079275 -2.6375 0.008352 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##### Model 2: Multivariate regression of electoral violence and voter turnout ####
# Specify model 2
model2 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events.Dummy +
RDR.Vote.Share.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df_matched,
family = binomial(link = logit),
weights = weights
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model2, vcov = vcovHC(model2, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.6073330 0.4996133 1.2156 0.2241350
## Electoral.Violence.Events.Dummy -0.0587936 0.0486425 -1.2087 0.2267826
## RDR.Vote.Share.2010 -0.1129506 0.2302935 -0.4905 0.6238058
## Electoral.Violence.Events.Spatial.Lag -0.0093317 0.0192862 -0.4839 0.6284917
## Electoral.Violence.Events.2011 -0.0164052 0.0033249 -4.9340 8.055e-07
## Number.of.Seats.2021 0.0230420 0.0492238 0.4681 0.6397081
## Voter.Turnout.2016 1.5046949 0.3339816 4.5053 6.627e-06
## Poverty.Ratio 0.1660696 0.1372222 1.2102 0.2261930
## Population.2014.Logged -0.1490904 0.0389512 -3.8276 0.0001294
##
## (Intercept)
## Electoral.Violence.Events.Dummy
## RDR.Vote.Share.2010
## Electoral.Violence.Events.Spatial.Lag
## Electoral.Violence.Events.2011 ***
## Number.of.Seats.2021
## Voter.Turnout.2016 ***
## Poverty.Ratio
## Population.2014.Logged ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##### Model 3: Multivariate regression of electoral violence and voter turnout with interaction ####
# Specify Model 3
model3 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events.Dummy * RDR.Vote.Share.2010 +
RDR.Vote.Share.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df_matched,
family = binomial(link = logit),
weights = weights
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model3, vcov = vcovHC(model3, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error
## (Intercept) 0.2379663 0.4273351
## Electoral.Violence.Events.Dummy 0.1029496 0.1006419
## RDR.Vote.Share.2010 0.2466827 0.2231832
## Electoral.Violence.Events.Spatial.Lag -0.0074877 0.0193183
## Electoral.Violence.Events.2011 -0.0165980 0.0034273
## Number.of.Seats.2021 0.0203234 0.0547438
## Voter.Turnout.2016 1.6596742 0.2672605
## Poverty.Ratio 0.1525531 0.1416754
## Population.2014.Logged -0.1260252 0.0363643
## Electoral.Violence.Events.Dummy:RDR.Vote.Share.2010 -0.8216938 0.4733287
## z value Pr(>|z|)
## (Intercept) 0.5569 0.577622
## Electoral.Violence.Events.Dummy 1.0229 0.306341
## RDR.Vote.Share.2010 1.1053 0.269033
## Electoral.Violence.Events.Spatial.Lag -0.3876 0.698315
## Electoral.Violence.Events.2011 -4.8429 1.279e-06 ***
## Number.of.Seats.2021 0.3712 0.710454
## Voter.Turnout.2016 6.2099 5.300e-10 ***
## Poverty.Ratio 1.0768 0.281579
## Population.2014.Logged -3.4656 0.000529 ***
## Electoral.Violence.Events.Dummy:RDR.Vote.Share.2010 -1.7360 0.082566 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Calculate predicted values
predictions(
model3,
newdata = datagrid(
RDR.Vote.Share.2010 = c(0.1, 0.7),
Electoral.Violence.Events.Dummy = c(0, 1)
),
vcov = sandwich::vcovHC(model3, type = "HC")
)
## rowid type predicted std.error statistic p.value conf.low
## 1 1 response 0.4451937 0.014369803 30.981197 9.659665e-211 0.4172344
## 2 2 response 0.4503320 0.008702945 51.744788 0.000000e+00 0.4333394
## 3 3 response 0.4819828 0.024491746 19.679398 3.238249e-86 0.4342919
## 4 4 response 0.3671795 0.051534608 7.124911 1.041480e-12 0.2730834
## conf.high Voter.Turnout.2021 Electoral.Violence.Events.Spatial.Lag
## 1 0.4735043 0.4748526 1.575587
## 2 0.4674413 0.4748526 1.575587
## 3 0.5300043 0.4748526 1.575587
## 4 0.4726180 0.4748526 1.575587
## Electoral.Violence.Events.2011 Number.of.Seats.2021 Voter.Turnout.2016
## 1 1 1.218182 0.4526667
## 2 1 1.218182 0.4526667
## 3 1 1.218182 0.4526667
## 4 1 1.218182 0.4526667
## Poverty.Ratio Population.2014.Logged weights RDR.Vote.Share.2010
## 1 0.5268865 10.4008 1 0.1
## 2 0.5268865 10.4008 1 0.1
## 3 0.5268865 10.4008 1 0.7
## 4 0.5268865 10.4008 1 0.7
## Electoral.Violence.Events.Dummy
## 1 0
## 2 1
## 3 0
## 4 1
###### Make marginal effects plot ####
# Calculate marginal effects for different levels of incumbent strength
marginal3 <- plot_cme(
model3, effect = "Electoral.Violence.Events.Dummy",
condition = "RDR.Vote.Share.2010",
vcov = sandwich::vcovHC(model3, type = "HC"),
draw = FALSE
)
# Define transform value for y-scale
coeff <- 0.4
# Make conditional effects plot with super-imposed distribution of incumbent strength
ggplot() +
geom_histogram(data = df_matched, aes(x = RDR.Vote.Share.2010, y = (..count..) * 0.01), fill = alpha("#482878FF", 0.8)) +
geom_line(data = marginal3, aes(x = condition1, y = comparison + coeff)) +
geom_ribbon(data = marginal3, aes(x = condition1, ymin = conf.low + coeff, ymax = conf.high + coeff), fill = "#482878FF", alpha = 0.4) +
scale_y_continuous(
breaks = seq(0, 0.8, 0.1),
labels = seq(-0.4, 0.4, 0.1),
sec.axis = sec_axis(
trans = ~. * 100,
name = "Number of observations",
breaks = seq(0, 50, 10)
)
) +
scale_x_continuous(breaks = seq(0, 1, 0.2), limits = c(0, 1), labels = scales::percent) +
geom_hline(yintercept = 0.4, size = 0.5, linetype = 2) +
labs(
y = "Marginal effect of electoral violence on turnout",
x = "Incumbent vote share",
title = NULL
) +
theme_bw() +
theme(
plot.margin = unit(c(1,1,1,1), "cm"),
axis.title.y = element_text(margin = margin (t = 0, r = 10, b = 0, l = 0), size = 14),
axis.title.x = element_text(margin = margin (t = 10, r = 0, b = 0, l = 0), size = 14),
axis.title.y.right = element_text(margin = margin (t = 0, r = 0, b = 0, l = 10), size = 14),
axis.text.x = element_text(size = 12),
axis.text.y = element_text(size = 12),
legend.position = "bottom"
)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 2 rows containing missing values (`geom_bar()`).

ggsave("figure_a5.jpg", height = 15, width = 17, units = "cm", dpi = 600)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 2 rows containing missing values (`geom_bar()`).
##### Make regression table ####
# Create lists of robust standard errors
robust_se1 <- sqrt(diag(vcovHC(model1, type = "HC")))
robust_se2 <- sqrt(diag(vcovHC(model2, type = "HC")))
robust_se3 <- sqrt(diag(vcovHC(model3, type = "HC")))
# Create lists of McFadden's Adjusted R2
mcfadden1 <- format(round(PseudoR2(model1, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden2 <- format(round(PseudoR2(model2, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden3 <- format(round(PseudoR2(model3, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
# Make regression table
stargazer(
model1,
model2,
model3,
title = "Fractional regression of voter turnout and electoral violence (matched sample)",
label = "tab:reg-matched",
align = TRUE,
column.sep.width = "5pt",
no.space = TRUE,
omit.stat = c("LL", "ser", "f"),
se = list(robust_se1, robust_se2, robust_se3),
dep.var.labels = "Voter turnout",
digits = 2,
font.size = "footnotesize",
single.row = FALSE,
omit.table.layout = "ld",
covariate.labels = c(
"Electoral violence (dummy)",
"Incumbent strength",
"Electoral violence (spatial lag)",
"Past electoral violence",
"Number of seats",
"Past voter turnout",
"Poverty ratio",
"Logged population size",
"Electoral violence (dummy) x Incumbent strength"
),
add.lines = list(c("McFadden's Adjusted R2", mcfadden1, mcfadden2, mcfadden3)),
notes.append = FALSE,
star.cutoffs = c(.1, .05, .01),
type = "text",
out = "table_a3"
)
##
## Fractional regression of voter turnout and electoral violence (matched sample)
## =============================================================================
## (1) (2) (3)
## -----------------------------------------------------------------------------
## Electoral violence (dummy) -0.21*** -0.06 0.10
## (0.08) (0.05) (0.10)
## Incumbent strength -0.11 0.25
## (0.23) (0.22)
## Electoral violence (spatial lag) -0.01 -0.01
## (0.02) (0.02)
## Past electoral violence -0.02*** -0.02***
## (0.003) (0.003)
## Number of seats 0.02 0.02
## (0.05) (0.05)
## Past voter turnout 1.50*** 1.66***
## (0.33) (0.27)
## Poverty ratio 0.17 0.15
## (0.14) (0.14)
## Logged population size -0.15*** -0.13***
## (0.04) (0.04)
## Electoral violence (dummy) x Incumbent strength -0.82*
## (0.47)
## Constant -0.21*** 0.61 0.24
## (0.07) (0.50) (0.43)
## -----------------------------------------------------------------------------
## McFadden's Adjusted R2 0.00 -0.02 -0.04
## Observations 165 165 165
## Akaike Inf. Crit. 166.32 169.55 172.67
## =============================================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
#### Placebo test using competitiveness instead of incumbent strength ####
# Specify Model 1
model1 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events * Competitiveness.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model1, vcov = vcovHC(model1, type="HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value
## (Intercept) -0.0799755 0.5642506 -0.1417
## Electoral.Violence.Events 0.0075840 0.0168450 0.4502
## Competitiveness.2010 0.0163164 0.0087472 1.8653
## Electoral.Violence.Events.Spatial.Lag -0.0126757 0.0137670 -0.9207
## Electoral.Violence.Events.2011 -0.0159074 0.0058592 -2.7150
## Number.of.Seats.2021 0.0214877 0.0531920 0.4040
## Voter.Turnout.2016 2.0415557 0.3986924 5.1206
## Poverty.Ratio 0.2178748 0.1367228 1.5936
## Population.2014.Logged -0.1083528 0.0446018 -2.4293
## Electoral.Violence.Events:Competitiveness.2010 -0.0088273 0.0082075 -1.0755
## Pr(>|z|)
## (Intercept) 0.887287
## Electoral.Violence.Events 0.652550
## Competitiveness.2010 0.062135 .
## Electoral.Violence.Events.Spatial.Lag 0.357194
## Electoral.Violence.Events.2011 0.006628 **
## Number.of.Seats.2021 0.686238
## Voter.Turnout.2016 3.045e-07 ***
## Poverty.Ratio 0.111037
## Population.2014.Logged 0.015126 *
## Electoral.Violence.Events:Competitiveness.2010 0.282140
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Specify Model 2
model2 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events * Competitiveness.2010 +
Electoral.Violence.Events * RDR.Vote.Share.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model2, vcov = vcovHC(model2, type="HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value
## (Intercept) -0.3328675 0.5119688 -0.6502
## Electoral.Violence.Events 0.1200190 0.0376706 3.1860
## Competitiveness.2010 0.0092557 0.0095050 0.9738
## RDR.Vote.Share.2010 0.3868197 0.1303735 2.9670
## Electoral.Violence.Events.Spatial.Lag 0.0020749 0.0121412 0.1709
## Electoral.Violence.Events.2011 -0.0141634 0.0060242 -2.3511
## Number.of.Seats.2021 0.0478177 0.0593053 0.8063
## Voter.Turnout.2016 1.9935567 0.3639808 5.4771
## Poverty.Ratio 0.2207420 0.1322867 1.6687
## Population.2014.Logged -0.0969349 0.0379612 -2.5535
## Electoral.Violence.Events:Competitiveness.2010 -0.0168950 0.0055295 -3.0554
## Electoral.Violence.Events:RDR.Vote.Share.2010 -0.5165671 0.1449669 -3.5633
## Pr(>|z|)
## (Intercept) 0.5155814
## Electoral.Violence.Events 0.0014425 **
## Competitiveness.2010 0.3301699
## RDR.Vote.Share.2010 0.0030071 **
## Electoral.Violence.Events.Spatial.Lag 0.8643056
## Electoral.Violence.Events.2011 0.0187196 *
## Number.of.Seats.2021 0.4200713
## Voter.Turnout.2016 4.324e-08 ***
## Poverty.Ratio 0.0951841 .
## Population.2014.Logged 0.0106639 *
## Electoral.Violence.Events:Competitiveness.2010 0.0022476 **
## Electoral.Violence.Events:RDR.Vote.Share.2010 0.0003662 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Create lists of robust standard errors
robust_se1 <- sqrt(diag(vcovHC(model1, type = "HC")))
robust_se2 <- sqrt(diag(vcovHC(model2, type = "HC")))
# Create lists of McFadden's Adjusted R2
mcfadden1 <- format(round(PseudoR2(model1, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden2 <- format(round(PseudoR2(model2, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
# Make regression table
stargazer(
model1,
model2,
title = "Placebo test",
label = "tab:reg-placebo",
align = TRUE,
column.sep.width = "5pt",
no.space = TRUE,
omit.stat = c("LL", "ser", "f"),
se = list(robust_se1, robust_se2),
digits = 2,
font.size = "footnotesize",
single.row = FALSE,
omit.table.layout = "ld",
covariate.labels = c(
"Electoral violence",
"Competitiveness",
"Incumbent strength",
"Electoral violence (spatial lag)",
"Past electoral violence",
"Number of seats",
"Past voter turnout",
"Poverty ratio",
"Logged population size",
"Electoral violence x Competitiveness",
"Electoral violence x Incumbent strength"
),
add.lines = list(c("McFadden's Adjusted R2", mcfadden1, mcfadden2)),
notes.append = FALSE,
star.cutoffs = c(.1, .05, .01),
type = "text",
out = "table_a4"
)
##
## Placebo test
## ====================================================================
## (1) (2)
## --------------------------------------------------------------------
## Electoral violence 0.01 0.12***
## (0.02) (0.04)
## Competitiveness 0.02* 0.01
## (0.01) (0.01)
## Incumbent strength 0.39***
## (0.13)
## Electoral violence (spatial lag) -0.01 0.002
## (0.01) (0.01)
## Past electoral violence -0.02*** -0.01**
## (0.01) (0.01)
## Number of seats 0.02 0.05
## (0.05) (0.06)
## Past voter turnout 2.04*** 1.99***
## (0.40) (0.36)
## Poverty ratio 0.22 0.22*
## (0.14) (0.13)
## Logged population size -0.11** -0.10**
## (0.04) (0.04)
## Electoral violence x Competitiveness -0.01 -0.02***
## (0.01) (0.01)
## Electoral violence x Incumbent strength -0.52***
## (0.14)
## Constant -0.08 -0.33
## (0.56) (0.51)
## --------------------------------------------------------------------
## McFadden's Adjusted R2 0.16 0.16
## Observations 205 205
## Akaike Inf. Crit. 235.19 235.21
## ====================================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
##### Disaggregating the timing of violence ####
df <- df %>% mutate(
Pre.Election.Dummy = case_when(Pre.Electoral.Violence.Events > 0 ~ 1, TRUE ~ 0),
Post.Election.Dummy = case_when(Post.Electoral.Violence.Events > 0 ~ 1, TRUE ~ 0)
)
# Specify model 1
model1 <- glm(
Voter.Turnout.2021 ~
Pre.Electoral.Violence.Events * RDR.Vote.Share.2010 +
Post.Electoral.Violence.Events * RDR.Vote.Share.2010 +
RDR.Vote.Share.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model1, vcov = vcovHC(model1, type="HC"))
##
## z test of coefficients:
##
## Estimate Std. Error
## (Intercept) -0.0028572 0.5532268
## Pre.Electoral.Violence.Events 0.0456333 0.0419336
## RDR.Vote.Share.2010 0.5190705 0.1471362
## Post.Electoral.Violence.Events 0.0396251 0.0690563
## Electoral.Violence.Events.Spatial.Lag 0.0043576 0.0122256
## Electoral.Violence.Events.2011 -0.0102491 0.0073364
## Number.of.Seats.2021 0.0558576 0.0671906
## Voter.Turnout.2016 1.8530984 0.3958443
## Poverty.Ratio 0.2151649 0.1347335
## Population.2014.Logged -0.1240449 0.0432725
## Pre.Electoral.Violence.Events:RDR.Vote.Share.2010 -0.3493677 0.2390653
## RDR.Vote.Share.2010:Post.Electoral.Violence.Events -0.3203696 0.3772652
## z value Pr(>|z|)
## (Intercept) -0.0052 0.995879
## Pre.Electoral.Violence.Events 1.0882 0.276495
## RDR.Vote.Share.2010 3.5278 0.000419 ***
## Post.Electoral.Violence.Events 0.5738 0.566097
## Electoral.Violence.Events.Spatial.Lag 0.3564 0.721517
## Electoral.Violence.Events.2011 -1.3970 0.162405
## Number.of.Seats.2021 0.8313 0.405787
## Voter.Turnout.2016 4.6814 2.849e-06 ***
## Poverty.Ratio 1.5970 0.110273
## Population.2014.Logged -2.8666 0.004149 **
## Pre.Electoral.Violence.Events:RDR.Vote.Share.2010 -1.4614 0.143908
## RDR.Vote.Share.2010:Post.Electoral.Violence.Events -0.8492 0.395776
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Create lists of robust standard errors
robust_se1 <- sqrt(diag(vcovHC(model1, type = "HC")))
# Create lists of McFadden's Adjusted R2
mcfadden1 <- format(round(PseudoR2(model1, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
# Make regression table
stargazer(
model1,
title = "Disaggregating electoral violence by timing",
label = "tab:reg-timing",
align = TRUE,
column.sep.width = "5pt",
no.space = TRUE,
omit.stat = c("LL", "ser", "f"),
se = list(robust_se1, robust_se2),
dep.var.labels = "Voter turnout",
digits = 2,
font.size = "scriptsize",
single.row = FALSE,
omit.table.layout = "ld",
order = c(1,2,4,5,3),
covariate.labels = c(
"Pre-electoral violence",
"Post-electoral violence",
"Incumbent strength",
"Electoral violence (spatial lag)",
"Past electoral violence",
"Number of seats",
"Past voter turnout",
"Poverty ratio",
"Logged population size",
"Pre-electoral violence x Incumbent strength",
"Post-electoral violence x Incumbent strength"
),
add.lines = list(c("McFadden's Adjusted R2", mcfadden1, mcfadden2)),
notes.append = FALSE,
star.cutoffs = c(.1, .05, .01),
type = "text",
out = "table_a5"
)
##
## Disaggregating electoral violence by timing
## ========================================================================
## Pre-electoral violence 0.05
## (0.04)
## Post-electoral violence 0.52***
## (0.15)
## Incumbent strength 0.004
## (0.01)
## Electoral violence (spatial lag) -0.01
## (0.01)
## Past electoral violence 0.04
## (0.07)
## Number of seats 0.06
## (0.07)
## Past voter turnout 1.85***
## (0.40)
## Poverty ratio 0.22
## (0.13)
## Logged population size -0.12***
## (0.04)
## Pre-electoral violence x Incumbent strength -0.35
## (0.24)
## Post-electoral violence x Incumbent strength -0.32
## (0.38)
## Constant -0.003
## (0.55)
## ------------------------------------------------------------------------
## McFadden's Adjusted R2 0.15
## Observations 205
## Akaike Inf. Crit. 236.77
## ========================================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
#### Using a dichotomous independent and moderating variable ####
# Create RDR stronghold variable
df <- df %>% mutate(RDR.Stronghold.2010 = case_when(RDR.Vote.Share.2010 >= 0.5 ~ 1, TRUE ~ 0))
# Specify Model 1
model1 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events.Dummy,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model1, vcov = vcovHC(model1, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.180784 0.063831 2.8322 0.004623 **
## Electoral.Violence.Events.Dummy -0.598622 0.077105 -7.7637 8.249e-15 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Specify model 2
model2 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events.Dummy +
RDR.Stronghold.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model2, vcov = vcovHC(model2, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.10591008 0.61991581 0.1708 0.864345
## Electoral.Violence.Events.Dummy -0.13796516 0.05768903 -2.3915 0.016778
## RDR.Stronghold.2010 0.20555580 0.07924043 2.5941 0.009485
## Electoral.Violence.Events.Spatial.Lag 0.00059932 0.01352654 0.0443 0.964660
## Electoral.Violence.Events.2011 -0.01553638 0.00576369 -2.6956 0.007027
## Number.of.Seats.2021 0.03010784 0.05892999 0.5109 0.609415
## Voter.Turnout.2016 1.99406444 0.40695773 4.8999 9.587e-07
## Poverty.Ratio 0.17353596 0.13563807 1.2794 0.200755
## Population.2014.Logged -0.11908580 0.04750273 -2.5069 0.012179
##
## (Intercept)
## Electoral.Violence.Events.Dummy *
## RDR.Stronghold.2010 **
## Electoral.Violence.Events.Spatial.Lag
## Electoral.Violence.Events.2011 **
## Number.of.Seats.2021
## Voter.Turnout.2016 ***
## Poverty.Ratio
## Population.2014.Logged *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Specify Model 3
model3 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events.Dummy * RDR.Stronghold.2010 +
RDR.Stronghold.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df,
family = binomial(link = logit),
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model3, vcov = vcovHC(model3, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error
## (Intercept) 0.01818816 0.53287907
## Electoral.Violence.Events.Dummy -0.05941486 0.03812425
## RDR.Stronghold.2010 0.30433616 0.09369682
## Electoral.Violence.Events.Spatial.Lag 0.00069134 0.01298694
## Electoral.Violence.Events.2011 -0.01556197 0.00571512
## Number.of.Seats.2021 0.04043323 0.06064715
## Voter.Turnout.2016 2.00037497 0.36048658
## Poverty.Ratio 0.19516478 0.13423830
## Population.2014.Logged -0.11780059 0.04130528
## Electoral.Violence.Events.Dummy:RDR.Stronghold.2010 -0.52428503 0.26236273
## z value Pr(>|z|)
## (Intercept) 0.0341 0.972772
## Electoral.Violence.Events.Dummy -1.5585 0.119126
## RDR.Stronghold.2010 3.2481 0.001162 **
## Electoral.Violence.Events.Spatial.Lag 0.0532 0.957546
## Electoral.Violence.Events.2011 -2.7229 0.006470 **
## Number.of.Seats.2021 0.6667 0.504966
## Voter.Turnout.2016 5.5491 2.871e-08 ***
## Poverty.Ratio 1.4539 0.145983
## Population.2014.Logged -2.8520 0.004345 **
## Electoral.Violence.Events.Dummy:RDR.Stronghold.2010 -1.9983 0.045682 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Create lists of robust standard errors
robust_se1 <- sqrt(diag(vcovHC(model1, type = "HC")))
robust_se2 <- sqrt(diag(vcovHC(model2, type = "HC")))
robust_se3 <- sqrt(diag(vcovHC(model3, type = "HC")))
# Create lists of McFadden's Adjusted R2
mcfadden1 <- format(round(PseudoR2(model1, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden2 <- format(round(PseudoR2(model2, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden3 <- format(round(PseudoR2(model3, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
# Make regression table
stargazer(
model1,
model2,
model3,
title = "Fractional regression using a dichotomous independent and moderating variable)",
label = "tab:reg-dummies",
align = TRUE,
column.sep.width = "5pt",
no.space = TRUE,
omit.stat = c("LL", "ser", "f"),
se = list(robust_se1, robust_se2, robust_se3),
dep.var.labels = "Voter turnout",
digits = 2,
font.size = "footnotesize",
single.row = FALSE,
omit.table.layout = "ld",
covariate.labels = c(
"Electoral violence (dummy)",
"Incumbent stronghold (dummy)",
"Electoral violence (spatial lag)",
"Past electoral violence",
"Number of seats",
"Past voter turnout",
"Poverty ratio",
"Logged population size",
"Electoral violence (dummy) x Incumbent stronghold (dummy)"
),
add.lines = list(c("McFadden's Adjusted R2", mcfadden1, mcfadden2, mcfadden3)),
notes.append = FALSE,
star.cutoffs = c(.1, .05, .01),
type = "text",
out = "table_a6"
)
##
## Fractional regression using a dichotomous independent and moderating variable)
## =======================================================================================
## (1) (2) (3)
## ---------------------------------------------------------------------------------------
## Electoral violence (dummy) -0.60*** -0.14** -0.06
## (0.08) (0.06) (0.04)
## Incumbent stronghold (dummy) 0.21*** 0.30***
## (0.08) (0.09)
## Electoral violence (spatial lag) 0.001 0.001
## (0.01) (0.01)
## Past electoral violence -0.02*** -0.02***
## (0.01) (0.01)
## Number of seats 0.03 0.04
## (0.06) (0.06)
## Past voter turnout 1.99*** 2.00***
## (0.41) (0.36)
## Poverty ratio 0.17 0.20
## (0.14) (0.13)
## Logged population size -0.12** -0.12***
## (0.05) (0.04)
## Electoral violence (dummy) x Incumbent stronghold (dummy) -0.52**
## (0.26)
## Constant 0.18*** 0.11 0.02
## (0.06) (0.62) (0.53)
## ---------------------------------------------------------------------------------------
## McFadden's Adjusted R2 0.06 0.17 0.16
## Observations 205 205 205
## Akaike Inf. Crit. 261.91 232.84 233.49
## =======================================================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
#### Using a different measure of electoral violence ####
# Specify Model 1
model1 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Severity,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model1, vcov = vcovHC(model1, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.0907910 0.0447477 -2.0290 0.04246 *
## Electoral.Violence.Severity -0.0024985 0.0018600 -1.3433 0.17917
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Specify model 2
model2 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Severity +
RDR.Vote.Share.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model2, vcov = vcovHC(model2, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.13547526 0.64511858 0.2100 0.833667
## Electoral.Violence.Severity 0.00018143 0.00042857 0.4233 0.672041
## RDR.Vote.Share.2010 0.45147661 0.13847588 3.2603 0.001113
## Electoral.Violence.Events.Spatial.Lag -0.00053941 0.01284529 -0.0420 0.966505
## Electoral.Violence.Events.2011 -0.01558330 0.00554108 -2.8123 0.004919
## Number.of.Seats.2021 0.02116342 0.05837540 0.3625 0.716948
## Voter.Turnout.2016 1.92220622 0.42094021 4.5665 4.96e-06
## Poverty.Ratio 0.23021371 0.13933490 1.6522 0.098487
## Population.2014.Logged -0.13711153 0.05165877 -2.6542 0.007950
##
## (Intercept)
## Electoral.Violence.Severity
## RDR.Vote.Share.2010 **
## Electoral.Violence.Events.Spatial.Lag
## Electoral.Violence.Events.2011 **
## Number.of.Seats.2021
## Voter.Turnout.2016 ***
## Poverty.Ratio .
## Population.2014.Logged **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Specify Model 3
model3 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Severity * RDR.Vote.Share.2010 +
RDR.Vote.Share.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model3, vcov = vcovHC(model3, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value
## (Intercept) 0.14806321 0.64337823 0.2301
## Electoral.Violence.Severity 0.00222058 0.00086028 2.5812
## RDR.Vote.Share.2010 0.44997028 0.13786230 3.2639
## Electoral.Violence.Events.Spatial.Lag -0.00122491 0.01279965 -0.0957
## Electoral.Violence.Events.2011 -0.01610927 0.00560927 -2.8719
## Number.of.Seats.2021 0.02560662 0.05858132 0.4371
## Voter.Turnout.2016 1.89242272 0.42291638 4.4747
## Poverty.Ratio 0.23057635 0.13842186 1.6658
## Population.2014.Logged -0.13674550 0.05141618 -2.6596
## Electoral.Violence.Severity:RDR.Vote.Share.2010 -0.03100390 0.01432125 -2.1649
## Pr(>|z|)
## (Intercept) 0.817988
## Electoral.Violence.Severity 0.009845 **
## RDR.Vote.Share.2010 0.001099 **
## Electoral.Violence.Events.Spatial.Lag 0.923760
## Electoral.Violence.Events.2011 0.004080 **
## Number.of.Seats.2021 0.662030
## Voter.Turnout.2016 7.652e-06 ***
## Poverty.Ratio 0.095763 .
## Population.2014.Logged 0.007824 **
## Electoral.Violence.Severity:RDR.Vote.Share.2010 0.030396 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Create lists of robust standard errors
robust_se1 <- sqrt(diag(vcovHC(model1, type = "HC")))
robust_se2 <- sqrt(diag(vcovHC(model2, type = "HC")))
robust_se3 <- sqrt(diag(vcovHC(model3, type = "HC")))
# Create lists of McFadden's Adjusted R2
mcfadden1 <- format(round(PseudoR2(model1, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden2 <- format(round(PseudoR2(model2, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden3 <- format(round(PseudoR2(model3, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
# Make regression table
stargazer(
model1,
model2,
model3,
title = "Using A Different Measure of Electoral Violence",
label = "tab:reg-severity",
align = TRUE,
column.sep.width = "5pt",
no.space = TRUE,
omit.stat = c("LL", "ser", "f"),
se = list(robust_se1, robust_se2, robust_se3),
dep.var.labels = "Voter turnout",
digits = 2,
font.size = "footnotesize",
single.row = FALSE,
omit.table.layout = "ld",
covariate.labels = c(
"Electoral violence severity",
"Incumbent strength",
"Electoral violence (spatial lag)",
"Past electoral violence",
"Number of seats",
"Past voter turnout",
"Poverty ratio",
"Logged population size",
"Electoral violence severity x Incumbent strength"
),
add.lines = list(c("McFadden's Adjusted R2", mcfadden1, mcfadden2, mcfadden3)),
notes.append = FALSE,
star.cutoffs = c(.1, .05, .01),
type = "text",
out = "table_a7"
)
##
## Using A Different Measure of Electoral Violence
## ==============================================================================
## (1) (2) (3)
## ------------------------------------------------------------------------------
## Electoral violence severity -0.002 0.0002 0.002***
## (0.002) (0.0004) (0.001)
## Incumbent strength 0.45*** 0.45***
## (0.14) (0.14)
## Electoral violence (spatial lag) -0.001 -0.001
## (0.01) (0.01)
## Past electoral violence -0.02*** -0.02***
## (0.01) (0.01)
## Number of seats 0.02 0.03
## (0.06) (0.06)
## Past voter turnout 1.92*** 1.89***
## (0.42) (0.42)
## Poverty ratio 0.23* 0.23*
## (0.14) (0.14)
## Logged population size -0.14*** -0.14***
## (0.05) (0.05)
## Electoral violence severity x Incumbent strength -0.03**
## (0.01)
## Constant -0.09** 0.14 0.15
## (0.04) (0.65) (0.64)
## ------------------------------------------------------------------------------
## McFadden's Adjusted R2 -0.01 0.17 0.16
## Observations 205 205 205
## Akaike Inf. Crit. 282.01 232.51 234.39
## ==============================================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
#### Excluding uncertain electoral violence events ####
# Specify Model 1
model1 <- glm(
Voter.Turnout.2021 ~ Electoral.Violence.Events.Clear,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model1, vcov = vcovHC(model1, type="HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.045662 0.051712 0.8830 0.3772
## Electoral.Violence.Events.Clear -0.110634 0.020497 -5.3976 6.752e-08 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Specify model 2
model2 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events.Clear +
RDR.Vote.Share.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model2, vcov = vcovHC(model2, type="HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.12313996 0.64111666 0.1921 0.847687
## Electoral.Violence.Events.Clear -0.01232859 0.00937716 -1.3147 0.188595
## RDR.Vote.Share.2010 0.42403149 0.13798257 3.0731 0.002119
## Electoral.Violence.Events.Spatial.Lag 0.00046792 0.01274406 0.0367 0.970711
## Electoral.Violence.Events.2011 -0.01363379 0.00564290 -2.4161 0.015688
## Number.of.Seats.2021 0.02608864 0.05990276 0.4355 0.663188
## Voter.Turnout.2016 1.92041625 0.42013539 4.5709 4.855e-06
## Poverty.Ratio 0.22251954 0.13742796 1.6192 0.105410
## Population.2014.Logged -0.13365946 0.05088303 -2.6268 0.008619
##
## (Intercept)
## Electoral.Violence.Events.Clear
## RDR.Vote.Share.2010 **
## Electoral.Violence.Events.Spatial.Lag
## Electoral.Violence.Events.2011 *
## Number.of.Seats.2021
## Voter.Turnout.2016 ***
## Poverty.Ratio
## Population.2014.Logged **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Specify model 3
model3 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events.Clear * RDR.Vote.Share.2010 +
RDR.Vote.Share.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model3, vcov = vcovHC(model3, type="HC"))
##
## z test of coefficients:
##
## Estimate Std. Error
## (Intercept) -0.0610841 0.5349425
## Electoral.Violence.Events.Clear 0.0512504 0.0267274
## RDR.Vote.Share.2010 0.5174814 0.1451112
## Electoral.Violence.Events.Spatial.Lag 0.0042803 0.0124983
## Electoral.Violence.Events.2011 -0.0100922 0.0074302
## Number.of.Seats.2021 0.0536312 0.0671489
## Voter.Turnout.2016 1.8886890 0.3782932
## Poverty.Ratio 0.2094304 0.1335000
## Population.2014.Logged -0.1195419 0.0416797
## Electoral.Violence.Events.Clear:RDR.Vote.Share.2010 -0.3884128 0.1684350
## z value Pr(>|z|)
## (Intercept) -0.1142 0.9090887
## Electoral.Violence.Events.Clear 1.9175 0.0551717 .
## RDR.Vote.Share.2010 3.5661 0.0003623 ***
## Electoral.Violence.Events.Spatial.Lag 0.3425 0.7320005
## Electoral.Violence.Events.2011 -1.3583 0.1743785
## Number.of.Seats.2021 0.7987 0.4244699
## Voter.Turnout.2016 4.9927 5.955e-07 ***
## Poverty.Ratio 1.5688 0.1167024
## Population.2014.Logged -2.8681 0.0041294 **
## Electoral.Violence.Events.Clear:RDR.Vote.Share.2010 -2.3060 0.0211101 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Create lists of robust standard errors
robust_se1 <- sqrt(diag(vcovHC(model1, type = "HC")))
robust_se2 <- sqrt(diag(vcovHC(model2, type = "HC")))
robust_se3 <- sqrt(diag(vcovHC(model3, type = "HC")))
# Create lists of McFadden's Adjusted R2
mcfadden1 <- format(round(PseudoR2(model1, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden2 <- format(round(PseudoR2(model2, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden3 <- format(round(PseudoR2(model3, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
# Make regression table
stargazer(
model1,
model2,
model3,
title = "Excluding uncertain electoral violence events",
label = "tab:reg-clear",
align = TRUE,
column.sep.width = "5pt",
no.space = TRUE,
omit.stat = c("LL", "ser", "f"),
se = list(robust_se1, robust_se2, robust_se3),
dep.var.labels = "Voter turnout",
digits = 2,
font.size = "footnotesize",
single.row = FALSE,
omit.table.layout = "ld",
covariate.labels = c(
"Electoral violence",
"Incumbent strength",
"Electoral violence (spatial lag)",
"Past electoral violence",
"Number of seats",
"Past voter turnout",
"Poverty ratio",
"Logged population size",
"Electoral violence x Incumbent strength"
),
add.lines = list(c("McFadden's Adjusted R2", mcfadden1, mcfadden2, mcfadden3)),
notes.append = FALSE,
star.cutoffs = c(.1, .05, .01),
type = "text",
out = "table_a8"
)
##
## Excluding uncertain electoral violence events
## =====================================================================
## (1) (2) (3)
## ---------------------------------------------------------------------
## Electoral violence -0.11*** -0.01 0.05*
## (0.02) (0.01) (0.03)
## Incumbent strength 0.42*** 0.52***
## (0.14) (0.15)
## Electoral violence (spatial lag) 0.0005 0.004
## (0.01) (0.01)
## Past electoral violence -0.01** -0.01
## (0.01) (0.01)
## Number of seats 0.03 0.05
## (0.06) (0.07)
## Past voter turnout 1.92*** 1.89***
## (0.42) (0.38)
## Poverty ratio 0.22 0.21
## (0.14) (0.13)
## Logged population size -0.13*** -0.12***
## (0.05) (0.04)
## Electoral violence x Incumbent strength -0.39**
## (0.17)
## Constant 0.05 0.12 -0.06
## (0.05) (0.64) (0.53)
## ---------------------------------------------------------------------
## McFadden's Adjusted R2 0.04 0.17 0.17
## Observations 205 205 205
## Akaike Inf. Crit. 268.81 232.29 232.95
## =====================================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
#### Using alternative measures of incumbent strength ####
# Create incumbent strength variable
df <- df %>%
mutate(Incumbent.Strength.2010 = RDR.Vote.Share.2010 * (RDR.Vote.Share.2010 / Competitor.Vote.Share.2010))
# Specify model 1
model1 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events * RDR.Margin.2010 +
RDR.Margin.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model1, vcov = vcovHC(model1, type="HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value
## (Intercept) 0.2929830 0.6025180 0.4863
## Electoral.Violence.Events -0.0622707 0.0288178 -2.1608
## RDR.Margin.2010 0.2974548 0.0810222 3.6713
## Electoral.Violence.Events.Spatial.Lag 0.0074347 0.0122517 0.6068
## Electoral.Violence.Events.2011 -0.0106475 0.0069729 -1.5270
## Number.of.Seats.2021 0.0463209 0.0649050 0.7137
## Voter.Turnout.2016 1.8508500 0.4056955 4.5622
## Poverty.Ratio 0.2105075 0.1338856 1.5723
## Population.2014.Logged -0.1324578 0.0461836 -2.8681
## Electoral.Violence.Events:RDR.Margin.2010 -0.1168377 0.0532093 -2.1958
## Pr(>|z|)
## (Intercept) 0.6267798
## Electoral.Violence.Events 0.0307076 *
## RDR.Margin.2010 0.0002413 ***
## Electoral.Violence.Events.Spatial.Lag 0.5439630
## Electoral.Violence.Events.2011 0.1267648
## Number.of.Seats.2021 0.4754300
## Voter.Turnout.2016 5.063e-06 ***
## Poverty.Ratio 0.1158824
## Population.2014.Logged 0.0041298 **
## Electoral.Violence.Events:RDR.Margin.2010 0.0281054 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Specify model 2
model2 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events * Incumbent.Strength.2010 +
Incumbent.Strength.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model2, vcov = vcovHC(model2, type="HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value
## (Intercept) -0.5327159 0.5442491 -0.9788
## Electoral.Violence.Events -0.0079332 0.0063937 -1.2408
## Incumbent.Strength.2010 0.0185577 0.0089182 2.0809
## Electoral.Violence.Events.Spatial.Lag -0.0074372 0.0121677 -0.6112
## Electoral.Violence.Events.2011 -0.0124801 0.0054722 -2.2806
## Number.of.Seats.2021 0.0114974 0.0525036 0.2190
## Voter.Turnout.2016 2.3063927 0.3934961 5.8613
## Poverty.Ratio 0.1499631 0.1292414 1.1603
## Population.2014.Logged -0.0696313 0.0399501 -1.7430
## Electoral.Violence.Events:Incumbent.Strength.2010 -0.0555242 0.0068927 -8.0555
## Pr(>|z|)
## (Intercept) 0.32767
## Electoral.Violence.Events 0.21469
## Incumbent.Strength.2010 0.03744 *
## Electoral.Violence.Events.Spatial.Lag 0.54105
## Electoral.Violence.Events.2011 0.02257 *
## Number.of.Seats.2021 0.82666
## Voter.Turnout.2016 4.593e-09 ***
## Poverty.Ratio 0.24591
## Population.2014.Logged 0.08134 .
## Electoral.Violence.Events:Incumbent.Strength.2010 7.918e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Specify model 3
model3 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events * RHDP.Vote.Share.2021 +
RHDP.Vote.Share.2021 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model3, vcov = vcovHC(model3, type="HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value
## (Intercept) 0.1847929 0.6251791 0.2956
## Electoral.Violence.Events 0.0364117 0.0191713 1.8993
## RHDP.Vote.Share.2021 0.7430948 0.2550484 2.9135
## Electoral.Violence.Events.Spatial.Lag -0.0025877 0.0131967 -0.1961
## Electoral.Violence.Events.2011 -0.0138857 0.0066606 -2.0847
## Number.of.Seats.2021 0.0276723 0.0635023 0.4358
## Voter.Turnout.2016 1.7718982 0.4272802 4.1469
## Poverty.Ratio 0.3155900 0.1390254 2.2700
## Population.2014.Logged -0.1521849 0.0511111 -2.9775
## Electoral.Violence.Events:RHDP.Vote.Share.2021 -0.1588508 0.0708909 -2.2408
## Pr(>|z|)
## (Intercept) 0.767548
## Electoral.Violence.Events 0.057527 .
## RHDP.Vote.Share.2021 0.003574 **
## Electoral.Violence.Events.Spatial.Lag 0.844542
## Electoral.Violence.Events.2011 0.037093 *
## Number.of.Seats.2021 0.663005
## Voter.Turnout.2016 3.37e-05 ***
## Poverty.Ratio 0.023207 *
## Population.2014.Logged 0.002906 **
## Electoral.Violence.Events:RHDP.Vote.Share.2021 0.025040 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Create lists of robust standard errors
robust_se1 <- sqrt(diag(vcovHC(model1, type = "HC")))
robust_se2 <- sqrt(diag(vcovHC(model2, type = "HC")))
robust_se3 <- sqrt(diag(vcovHC(model3, type = "HC")))
# Create lists of McFadden's Adjusted R2
mcfadden1 <- format(round(PseudoR2(model1, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden2 <- format(round(PseudoR2(model2, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden3 <- format(round(PseudoR2(model3, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
# Make regression table
stargazer(
model1,
model2,
model3,
title = "Using alternative measures of incumbent strength",
label = "tab:reg-alt",
align = TRUE,
column.sep.width = "5pt",
no.space = TRUE,
omit.stat = c("LL", "ser", "f"),
se = list(robust_se1, robust_se2, robust_se3),
dep.var.labels = "Voter turnout",
digits = 2,
font.size = "footnotesize",
single.row = FALSE,
omit.table.layout = "ld",
covariate.labels = c(
"Electoral violence",
"Incumbent margin of victory (2010)",
"Incumbent dominance (2010)",
"Incumbent vote share (2021)",
"Electoral violence (spatial lag)",
"Past electoral violence",
"Number of seats",
"Past voter turnout",
"Poverty ratio",
"Logged population size",
"Electoral violence x Incumbent margin of victory (2010)",
"Electoral violence x Incumbent dominance (2010)",
"Electoral violence x Incumbent vote share (2021)"
),
add.lines = list(c("McFadden's Adjusted R2", mcfadden1, mcfadden2, mcfadden3)),
notes.append = FALSE,
star.cutoffs = c(.1, .05, .01),
type = "text",
out = "table_a9"
)
##
## Using alternative measures of incumbent strength
## =====================================================================================
## (1) (2) (3)
## -------------------------------------------------------------------------------------
## Electoral violence -0.06** -0.01 0.04*
## (0.03) (0.01) (0.02)
## Incumbent margin of victory (2010) 0.30***
## (0.08)
## Incumbent dominance (2010) 0.02**
## (0.01)
## Incumbent vote share (2021) 0.74***
## (0.26)
## Electoral violence (spatial lag) 0.01 -0.01 -0.003
## (0.01) (0.01) (0.01)
## Past electoral violence -0.01 -0.01** -0.01**
## (0.01) (0.01) (0.01)
## Number of seats 0.05 0.01 0.03
## (0.06) (0.05) (0.06)
## Past voter turnout 1.85*** 2.31*** 1.77***
## (0.41) (0.39) (0.43)
## Poverty ratio 0.21 0.15 0.32**
## (0.13) (0.13) (0.14)
## Logged population size -0.13*** -0.07* -0.15***
## (0.05) (0.04) (0.05)
## Electoral violence x Incumbent margin of victory (2010) -0.12**
## (0.05)
## Electoral violence x Incumbent dominance (2010) -0.06***
## (0.01)
## Electoral violence x Incumbent vote share (2021) -0.16**
## (0.07)
## Constant 0.29 -0.53 0.18
## (0.60) (0.54) (0.63)
## -------------------------------------------------------------------------------------
## McFadden's Adjusted R2 0.17 0.17 0.16
## Observations 205 205 205
## Akaike Inf. Crit. 232.74 231.07 235.28
## =====================================================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
#### Excluding voting districts with irregular results ####
# Create variable of invalid ballots
df <- df %>% mutate(Missing.Votes = abs(1 - Sum.of.Vote.Shares.2021))
# Show summary statistics for invalid ballots
summary(df$Missing.Votes)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.00000 0.00950 0.01320 0.01585 0.02000 0.05820
# Specify model to examine the determinants of invalid ballots
missing.votes <- lm(
Missing.Votes ~
Electoral.Violence.Events +
RDR.Vote.Share.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df,
)
# Show results
summary(missing.votes)
##
## Call:
## lm(formula = Missing.Votes ~ Electoral.Violence.Events + RDR.Vote.Share.2010 +
## Electoral.Violence.Events.Spatial.Lag + Electoral.Violence.Events.2011 +
## Number.of.Seats.2021 + Voter.Turnout.2016 + Poverty.Ratio +
## Population.2014.Logged, data = df)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.019601 -0.006304 -0.002171 0.003633 0.045247
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3.779e-02 1.170e-02 3.231 0.00145 **
## Electoral.Violence.Events -1.290e-04 3.214e-04 -0.401 0.68867
## RDR.Vote.Share.2010 3.615e-04 3.331e-03 0.109 0.91367
## Electoral.Violence.Events.Spatial.Lag -2.920e-04 4.925e-04 -0.593 0.55393
## Electoral.Violence.Events.2011 5.748e-05 2.948e-04 0.195 0.84563
## Number.of.Seats.2021 9.504e-04 1.364e-03 0.697 0.48662
## Voter.Turnout.2016 -5.480e-03 6.373e-03 -0.860 0.39086
## Poverty.Ratio 7.150e-03 4.868e-03 1.469 0.14356
## Population.2014.Logged -2.300e-03 9.823e-04 -2.341 0.02021 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.01061 on 196 degrees of freedom
## Multiple R-squared: 0.07397, Adjusted R-squared: 0.03617
## F-statistic: 1.957 on 8 and 196 DF, p-value: 0.05376
# Calculate predicted values
predictions(
missing.votes,
newdata = datagrid(
Population.2014.Logged = c(7.85, 13.88)
),
vcov = sandwich::vcovHC(model3, type = "HC")
)
## rowid type predicted std.error statistic p.value conf.low conf.high
## 1 1 response 0.021663403 NA NA NA NA NA
## 2 2 response 0.007794214 NA NA NA NA NA
## Missing.Votes Electoral.Violence.Events RDR.Vote.Share.2010
## 1 0.01584923 2 0.3732313
## 2 0.01584923 2 0.3732313
## Electoral.Violence.Events.Spatial.Lag Electoral.Violence.Events.2011
## 1 1.744299 1
## 2 1.744299 1
## Number.of.Seats.2021 Voter.Turnout.2016 Poverty.Ratio Population.2014.Logged
## 1 1.243902 0.454901 0.5334743 7.85
## 2 1.243902 0.454901 0.5334743 13.88
# Make regression table
stargazer(
missing.votes,
title = "Linear regression of invalid ballots",
label = "tab:reg-invalid",
align = TRUE,
column.sep.width = "5pt",
no.space = TRUE,
omit.stat = c("LL", "ser", "f"),
dep.var.labels = "Share of invalid ballots",
digits = 2,
font.size = "footnotesize",
single.row = FALSE,
covariate.labels = c(
"Electoral violence",
"Incumbent strength",
"Electoral violence (spatial lag)",
"Past electoral violence",
"Number of seats",
"Past voter turnout",
"Poverty ratio",
"Logged population size"
),
notes.append = FALSE,
star.cutoffs = c(.1, .05, .01),
type = "text",
out = "table_a10"
)
##
## Linear regression of invalid ballots
## ============================================================
## Dependent variable:
## ---------------------------
## Share of invalid ballots
## ------------------------------------------------------------
## Electoral violence -0.0001
## (0.0003)
## Incumbent strength 0.0004
## (0.003)
## Electoral violence (spatial lag) -0.0003
## (0.0005)
## Past electoral violence 0.0001
## (0.0003)
## Number of seats 0.001
## (0.001)
## Past voter turnout -0.01
## (0.01)
## Poverty ratio 0.01
## (0.005)
## Logged population size -0.002**
## (0.001)
## Constant 0.04***
## (0.01)
## ------------------------------------------------------------
## Observations 205
## R2 0.07
## Adjusted R2 0.04
## ============================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
# Identify voting districts with suspected fraud
df <- df %>%
mutate(
Fraud = case_when(
Missing.Votes > 2 * sd(Missing.Votes) ~ 1,
Sum.of.Vote.Shares.2021 > 1 ~ 1,
TRUE ~ 0
)
)
# Subset data to voting districts without suspected fraud
df.fraud <- df %>% filter(Fraud == 0)
# Specify Model 1
model1 <- glm(
Voter.Turnout.2021 ~ Electoral.Violence.Events,
data = df.fraud,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model1, vcov = vcovHC(model1, type="HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.014965 0.063653 0.2351 0.8141
## Electoral.Violence.Events -0.086407 0.020192 -4.2792 1.876e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Specify model 2
model2 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events +
RDR.Vote.Share.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df.fraud,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model2, vcov = vcovHC(model2, type="HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.2787167 0.7507706 0.3712 0.7104582
## Electoral.Violence.Events -0.0049753 0.0090157 -0.5519 0.5810475
## RDR.Vote.Share.2010 0.6017427 0.1930678 3.1167 0.0018286
## Electoral.Violence.Events.Spatial.Lag -0.0027252 0.0146998 -0.1854 0.8529218
## Electoral.Violence.Events.2011 -0.0157165 0.0061571 -2.5526 0.0106924
## Number.of.Seats.2021 0.0346885 0.0630430 0.5502 0.5821575
## Voter.Turnout.2016 1.6837435 0.4894866 3.4398 0.0005821
## Poverty.Ratio 0.3762875 0.1621956 2.3200 0.0203429
## Population.2014.Logged -0.1510476 0.0597302 -2.5288 0.0114444
##
## (Intercept)
## Electoral.Violence.Events
## RDR.Vote.Share.2010 **
## Electoral.Violence.Events.Spatial.Lag
## Electoral.Violence.Events.2011 *
## Number.of.Seats.2021
## Voter.Turnout.2016 ***
## Poverty.Ratio *
## Population.2014.Logged *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Specify model 3
model3 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events * RDR.Vote.Share.2010 +
RDR.Vote.Share.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged,
data = df.fraud,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model3, vcov = vcovHC(model3, type="HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value
## (Intercept) 0.15614370 0.63789218 0.2448
## Electoral.Violence.Events 0.05209973 0.02680932 1.9433
## RDR.Vote.Share.2010 0.69717358 0.19745333 3.5308
## Electoral.Violence.Events.Spatial.Lag 0.00056673 0.01439793 0.0394
## Electoral.Violence.Events.2011 -0.01150441 0.00832545 -1.3818
## Number.of.Seats.2021 0.06586901 0.07213958 0.9131
## Voter.Turnout.2016 1.63692213 0.44233714 3.7006
## Poverty.Ratio 0.34258029 0.15725367 2.1785
## Population.2014.Logged -0.14104213 0.05010390 -2.8150
## Electoral.Violence.Events:RDR.Vote.Share.2010 -0.36829837 0.16744450 -2.1995
## Pr(>|z|)
## (Intercept) 0.8066262
## Electoral.Violence.Events 0.0519746 .
## RDR.Vote.Share.2010 0.0004143 ***
## Electoral.Violence.Events.Spatial.Lag 0.9686017
## Electoral.Violence.Events.2011 0.1670220
## Number.of.Seats.2021 0.3612019
## Voter.Turnout.2016 0.0002151 ***
## Poverty.Ratio 0.0293673 *
## Population.2014.Logged 0.0048778 **
## Electoral.Violence.Events:RDR.Vote.Share.2010 0.0278406 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Create lists of robust standard errors
robust_se1 <- sqrt(diag(vcovHC(model1, type = "HC")))
robust_se2 <- sqrt(diag(vcovHC(model2, type = "HC")))
robust_se3 <- sqrt(diag(vcovHC(model3, type = "HC")))
# Create lists of McFadden's Adjusted R2
mcfadden1 <- format(round(PseudoR2(model1, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden2 <- format(round(PseudoR2(model2, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden3 <- format(round(PseudoR2(model3, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
# Make regression table
stargazer(
model1,
model2,
model3,
title = "Exluding voting districts with irregular results",
label = "tab:reg-fraud",
align = TRUE,
column.sep.width = "5pt",
no.space = TRUE,
omit.stat = c("LL", "ser", "f"),
se = list(robust_se1, robust_se2, robust_se3),
dep.var.labels = "Voter turnout",
digits = 2,
font.size = "footnotesize",
single.row = FALSE,
omit.table.layout = "ld",
covariate.labels = c(
"Electoral violence",
"Incumbent strength",
"Electoral violence (spatial lag)",
"Past electoral violence",
"Number of seats",
"Past voter turnout",
"Poverty ratio",
"Logged population size",
"Electoral violence x Incumbent strength"
),
add.lines = list(c("McFadden's Adjusted R2", mcfadden1, mcfadden2, mcfadden3)),
notes.append = FALSE,
star.cutoffs = c(.1, .05, .01),
type = "text",
out = "table_a11"
)
##
## Exluding voting districts with irregular results
## =====================================================================
## (1) (2) (3)
## ---------------------------------------------------------------------
## Electoral violence -0.09*** -0.005 0.05*
## (0.02) (0.01) (0.03)
## Incumbent strength 0.60*** 0.70***
## (0.19) (0.20)
## Electoral violence (spatial lag) -0.003 0.001
## (0.01) (0.01)
## Past electoral violence -0.02** -0.01
## (0.01) (0.01)
## Number of seats 0.03 0.07
## (0.06) (0.07)
## Past voter turnout 1.68*** 1.64***
## (0.49) (0.44)
## Poverty ratio 0.38** 0.34**
## (0.16) (0.16)
## Logged population size -0.15** -0.14***
## (0.06) (0.05)
## Electoral violence x Incumbent strength -0.37**
## (0.17)
## Constant 0.01 0.28 0.16
## (0.06) (0.75) (0.64)
## ---------------------------------------------------------------------
## McFadden's Adjusted R2 0.02 0.14 0.13
## Observations 158 158 158
## Akaike Inf. Crit. 208.25 184.05 184.68
## =====================================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
#### Including region-level fixed effects ####
# Specify Model 1
model1 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events +
Region,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model1, vcov = vcovHC(model1, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.3628104 0.0378254 -9.5917 < 2.2e-16
## Electoral.Violence.Events -0.0456774 0.0088886 -5.1389 2.764e-07
## RegionBafing 0.8678742 0.1409116 6.1590 7.321e-10
## RegionBagoue 0.6111045 0.1149373 5.3168 1.056e-07
## RegionBelier 0.0996089 0.0897075 1.1104 0.2668382
## RegionBere 0.5623774 0.1034215 5.4377 5.397e-08
## RegionBounkani 0.6952080 0.1026094 6.7753 1.242e-11
## RegionCavally 0.3372025 0.2030297 1.6609 0.0967429
## RegionDistrict Autonome D'Abidjan -0.7405418 0.0852474 -8.6870 < 2.2e-16
## RegionDistrict Autonome De Yamoussoukro 0.2227761 0.1702801 1.3083 0.1907743
## RegionFolon 1.3606541 0.0733952 18.5387 < 2.2e-16
## RegionGbeke 0.2380020 0.0758420 3.1381 0.0017003
## RegionGbokle 0.0420420 0.0401770 1.0464 0.2953672
## RegionGoh -0.0303306 0.0600030 -0.5055 0.6132190
## RegionGontougo 0.7249091 0.0956581 7.5781 3.506e-14
## RegionGrands Ponts -0.2928396 0.0483001 -6.0629 1.337e-09
## RegionGuemon 0.2917602 0.0618076 4.7205 2.353e-06
## RegionHambol 0.3416898 0.1430698 2.3883 0.0169277
## RegionHaut-Sassandra 0.1033186 0.0892874 1.1571 0.2472125
## RegionIffou 0.6109789 0.1063761 5.7436 9.270e-09
## RegionIndenie-Djuablin 0.1896426 0.1167511 1.6243 0.1043048
## RegionKabadougou 1.2491157 0.2637861 4.7353 2.187e-06
## RegionLoh-Djiboua 0.1526165 0.1007043 1.5155 0.1296478
## RegionMarahoue -0.0403826 0.0570795 -0.7075 0.4792687
## RegionMe 0.3970270 0.1510807 2.6279 0.0085910
## RegionMoronou 0.4681146 0.0700868 6.6791 2.405e-11
## RegionN'Zi 0.2786488 0.1483247 1.8786 0.0602936
## RegionNawa -0.3255863 0.1226818 -2.6539 0.0079565
## RegionPoro 1.3478079 0.3494991 3.8564 0.0001151
## RegionSan Pedro -0.2734680 0.1021028 -2.6784 0.0073984
## RegionSud-Comoe 0.0393450 0.1069294 0.3680 0.7129082
## RegionTchologo 0.7744931 0.4199813 1.8441 0.0651666
## RegionTonkpi 0.3877225 0.1008694 3.8438 0.0001211
## RegionWorodougou 1.2624103 0.2744541 4.5997 4.231e-06
##
## (Intercept) ***
## Electoral.Violence.Events ***
## RegionBafing ***
## RegionBagoue ***
## RegionBelier
## RegionBere ***
## RegionBounkani ***
## RegionCavally .
## RegionDistrict Autonome D'Abidjan ***
## RegionDistrict Autonome De Yamoussoukro
## RegionFolon ***
## RegionGbeke **
## RegionGbokle
## RegionGoh
## RegionGontougo ***
## RegionGrands Ponts ***
## RegionGuemon ***
## RegionHambol *
## RegionHaut-Sassandra
## RegionIffou ***
## RegionIndenie-Djuablin
## RegionKabadougou ***
## RegionLoh-Djiboua
## RegionMarahoue
## RegionMe **
## RegionMoronou ***
## RegionN'Zi .
## RegionNawa **
## RegionPoro ***
## RegionSan Pedro **
## RegionSud-Comoe
## RegionTchologo .
## RegionTonkpi ***
## RegionWorodougou ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Specify model 2
model2 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events +
RDR.Vote.Share.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged +
Region,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model2, vcov = vcovHC(model2, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.1724644 0.6082607 -0.2835 0.7767652
## Electoral.Violence.Events -0.0192382 0.0097386 -1.9755 0.0482164
## RDR.Vote.Share.2010 0.1665995 0.2007531 0.8299 0.4066109
## Electoral.Violence.Events.Spatial.Lag 0.0088545 0.0145907 0.6069 0.5439451
## Electoral.Violence.Events.2011 -0.0036550 0.0054098 -0.6756 0.4992821
## Number.of.Seats.2021 0.0544081 0.0756090 0.7196 0.4717724
## Voter.Turnout.2016 1.3441701 0.5347744 2.5135 0.0119530
## Poverty.Ratio 0.3240532 0.1549422 2.0914 0.0364882
## Population.2014.Logged -0.1020971 0.0513901 -1.9867 0.0469550
## RegionBafing 0.4473357 0.1702481 2.6276 0.0086002
## RegionBagoue 0.1510323 0.1868658 0.8082 0.4189528
## RegionBelier 0.0277408 0.0566579 0.4896 0.6244035
## RegionBere 0.3755380 0.1855139 2.0243 0.0429381
## RegionBounkani 0.3319031 0.1380111 2.4049 0.0161768
## RegionCavally 0.2738049 0.1204670 2.2729 0.0230345
## RegionDistrict Autonome D'Abidjan -0.3092100 0.1197455 -2.5822 0.0098165
## RegionDistrict Autonome De Yamoussoukro 0.2408684 0.1053443 2.2865 0.0222258
## RegionFolon 0.7374542 0.2415868 3.0525 0.0022691
## RegionGbeke 0.1290824 0.0881842 1.4638 0.1432535
## RegionGbokle 0.2400873 0.0716300 3.3518 0.0008030
## RegionGoh 0.1603946 0.0726944 2.2064 0.0273544
## RegionGontougo 0.3854506 0.1479076 2.6060 0.0091600
## RegionGrands Ponts -0.1972464 0.0701998 -2.8098 0.0049575
## RegionGuemon 0.3010842 0.0736576 4.0876 4.358e-05
## RegionHambol 0.1790550 0.1885524 0.9496 0.3423004
## RegionHaut-Sassandra 0.1028688 0.0915245 1.1239 0.2610352
## RegionIffou 0.2777908 0.1307043 2.1253 0.0335584
## RegionIndenie-Djuablin 0.2397536 0.0932193 2.5719 0.0101133
## RegionKabadougou 0.6794817 0.5062377 1.3422 0.1795251
## RegionLoh-Djiboua 0.2039881 0.0820983 2.4847 0.0129667
## RegionMarahoue 0.1057374 0.0775684 1.3632 0.1728351
## RegionMe 0.3399990 0.0993217 3.4232 0.0006189
## RegionMoronou 0.3188697 0.1039173 3.0685 0.0021514
## RegionN'Zi 0.1552408 0.0764337 2.0311 0.0422497
## RegionNawa 0.0848608 0.1312524 0.6465 0.5179255
## RegionPoro 0.8623949 0.3505276 2.4603 0.0138830
## RegionSan Pedro 0.0343995 0.1262752 0.2724 0.7853014
## RegionSud-Comoe 0.1318190 0.1058094 1.2458 0.2128322
## RegionTchologo 0.2478112 0.3585513 0.6911 0.4894739
## RegionTonkpi 0.1760166 0.0946051 1.8605 0.0628090
## RegionWorodougou 0.6251201 0.3738395 1.6722 0.0944925
##
## (Intercept)
## Electoral.Violence.Events *
## RDR.Vote.Share.2010
## Electoral.Violence.Events.Spatial.Lag
## Electoral.Violence.Events.2011
## Number.of.Seats.2021
## Voter.Turnout.2016 *
## Poverty.Ratio *
## Population.2014.Logged *
## RegionBafing **
## RegionBagoue
## RegionBelier
## RegionBere *
## RegionBounkani *
## RegionCavally *
## RegionDistrict Autonome D'Abidjan **
## RegionDistrict Autonome De Yamoussoukro *
## RegionFolon **
## RegionGbeke
## RegionGbokle ***
## RegionGoh *
## RegionGontougo **
## RegionGrands Ponts **
## RegionGuemon ***
## RegionHambol
## RegionHaut-Sassandra
## RegionIffou *
## RegionIndenie-Djuablin *
## RegionKabadougou
## RegionLoh-Djiboua *
## RegionMarahoue
## RegionMe ***
## RegionMoronou **
## RegionN'Zi *
## RegionNawa
## RegionPoro *
## RegionSan Pedro
## RegionSud-Comoe
## RegionTchologo
## RegionTonkpi .
## RegionWorodougou .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Specify Model 3
model3 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events * RDR.Vote.Share.2010 +
RDR.Vote.Share.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged +
Region,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model3, vcov = vcovHC(model3, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value
## (Intercept) -2.5651e-01 5.8231e-01 -0.4405
## Electoral.Violence.Events 3.3547e-02 2.2649e-02 1.4812
## RDR.Vote.Share.2010 4.2664e-01 2.2696e-01 1.8798
## Electoral.Violence.Events.Spatial.Lag 8.2856e-03 1.4575e-02 0.5685
## Electoral.Violence.Events.2011 -1.3108e-05 7.0250e-03 -0.0019
## Number.of.Seats.2021 6.7418e-02 7.9925e-02 0.8435
## Voter.Turnout.2016 1.4173e+00 5.1050e-01 2.7763
## Poverty.Ratio 2.7915e-01 1.4779e-01 1.8889
## Population.2014.Logged -9.9348e-02 4.8617e-02 -2.0435
## RegionBafing 2.8610e-01 1.7839e-01 1.6038
## RegionBagoue -3.1175e-02 1.9832e-01 -0.1572
## RegionBelier -4.0657e-03 6.2907e-02 -0.0646
## RegionBere 1.7895e-01 1.9427e-01 0.9211
## RegionBounkani 2.5086e-01 1.3920e-01 1.8021
## RegionCavally 3.0232e-01 1.2240e-01 2.4698
## RegionDistrict Autonome D'Abidjan -2.8727e-01 1.2630e-01 -2.2745
## RegionDistrict Autonome De Yamoussoukro 2.7780e-01 1.2256e-01 2.2667
## RegionFolon 5.1740e-01 2.4730e-01 2.0922
## RegionGbeke 1.7100e-01 9.2848e-02 1.8417
## RegionGbokle 2.3486e-01 7.0642e-02 3.3246
## RegionGoh 1.8070e-01 7.7765e-02 2.3237
## RegionGontougo 3.3857e-01 1.4486e-01 2.3373
## RegionGrands Ponts -1.8526e-01 7.2487e-02 -2.5558
## RegionGuemon 2.7473e-01 9.3765e-02 2.9299
## RegionHambol 1.9071e-02 1.9532e-01 0.0976
## RegionHaut-Sassandra 1.8929e-01 9.5589e-02 1.9802
## RegionIffou 1.2722e-01 1.4213e-01 0.8951
## RegionIndenie-Djuablin 2.8374e-01 1.0583e-01 2.6811
## RegionKabadougou 4.6386e-01 5.1044e-01 0.9087
## RegionLoh-Djiboua 2.0759e-01 7.5041e-02 2.7664
## RegionMarahoue 1.0323e-01 7.9807e-02 1.2934
## RegionMe 2.9138e-01 9.6499e-02 3.0195
## RegionMoronou 2.7049e-01 1.2261e-01 2.2061
## RegionN'Zi 1.1666e-01 7.6855e-02 1.5180
## RegionNawa 7.6886e-02 1.2912e-01 0.5955
## RegionPoro 6.6334e-01 3.5104e-01 1.8896
## RegionSan Pedro 1.1636e-02 1.2725e-01 0.0914
## RegionSud-Comoe 1.3901e-01 9.6401e-02 1.4420
## RegionTchologo 1.2677e-01 3.4091e-01 0.3719
## RegionTonkpi 1.3647e-01 9.8506e-02 1.3854
## RegionWorodougou 4.4800e-01 3.6334e-01 1.2330
## Electoral.Violence.Events:RDR.Vote.Share.2010 -3.2585e-01 1.4214e-01 -2.2924
## Pr(>|z|)
## (Intercept) 0.6595652
## Electoral.Violence.Events 0.1385595
## RDR.Vote.Share.2010 0.0601295 .
## Electoral.Violence.Events.Spatial.Lag 0.5697063
## Electoral.Violence.Events.2011 0.9985113
## Number.of.Seats.2021 0.3989433
## Voter.Turnout.2016 0.0054988 **
## Poverty.Ratio 0.0589075 .
## Population.2014.Logged 0.0410027 *
## RegionBafing 0.1087566
## RegionBagoue 0.8750909
## RegionBelier 0.9484687
## RegionBere 0.3569805
## RegionBounkani 0.0715282 .
## RegionCavally 0.0135181 *
## RegionDistrict Autonome D'Abidjan 0.0229367 *
## RegionDistrict Autonome De Yamoussoukro 0.0234087 *
## RegionFolon 0.0364176 *
## RegionGbeke 0.0655201 .
## RegionGbokle 0.0008854 ***
## RegionGoh 0.0201404 *
## RegionGontougo 0.0194258 *
## RegionGrands Ponts 0.0105939 *
## RegionGuemon 0.0033902 **
## RegionHambol 0.9222196
## RegionHaut-Sassandra 0.0476802 *
## RegionIffou 0.3707178
## RegionIndenie-Djuablin 0.0073377 **
## RegionKabadougou 0.3634904
## RegionLoh-Djiboua 0.0056677 **
## RegionMarahoue 0.1958586
## RegionMe 0.0025315 **
## RegionMoronou 0.0273748 *
## RegionN'Zi 0.1290254
## RegionNawa 0.5515300
## RegionPoro 0.0588061 .
## RegionSan Pedro 0.9271384
## RegionSud-Comoe 0.1493158
## RegionTchologo 0.7100043
## RegionTonkpi 0.1659374
## RegionWorodougou 0.2175737
## Electoral.Violence.Events:RDR.Vote.Share.2010 0.0218807 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Create lists of robust standard errors
robust_se1 <- sqrt(diag(vcovHC(model1, type = "HC")))
robust_se2 <- sqrt(diag(vcovHC(model2, type = "HC")))
robust_se3 <- sqrt(diag(vcovHC(model3, type = "HC")))
# Create lists of McFadden's Adjusted R2
mcfadden1 <- format(round(PseudoR2(model1, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden2 <- format(round(PseudoR2(model2, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden3 <- format(round(PseudoR2(model3, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
# Make regression table
stargazer(
model1,
model2,
model3,
title = "Fixed effects fractional regression",
label = "tab:reg-fixed",
align = TRUE,
column.sep.width = "5pt",
no.space = TRUE,
omit.stat = c("LL", "ser", "f"),
se = list(robust_se1, robust_se2, robust_se3),
dep.var.labels = "Voter turnout",
digits = 2,
font.size = "footnotesize",
single.row = FALSE,
omit.table.layout = "ld",
covariate.labels = c(
"Electoral violence",
"Incumbent strength",
"Electoral violence (spatial lag)",
"Past electoral violence",
"Number of seats",
"Past voter turnout",
"Poverty ratio",
"Logged population size",
"Electoral violence x Incumbent strength"
),
omit = "Region",
add.lines = list(c("McFadden's Adjusted R2", mcfadden1, mcfadden2, mcfadden3)),
notes.append = FALSE,
star.cutoffs = c(.1, .05, .01),
type = "text",
out = "table_a12"
)
##
## Fixed effects fractional regression
## =====================================================================
## (1) (2) (3)
## ---------------------------------------------------------------------
## Electoral violence -0.05*** -0.02** 0.03
## (0.01) (0.01) (0.02)
## Incumbent strength 0.17 0.43*
## (0.20) (0.23)
## Electoral violence (spatial lag) 0.01 0.01
## (0.01) (0.01)
## Past electoral violence -0.004 -0.0000
## (0.01) (0.01)
## Number of seats 0.05 0.07
## (0.08) (0.08)
## Past voter turnout 1.34** 1.42***
## (0.53) (0.51)
## Poverty ratio 0.32** 0.28*
## (0.15) (0.15)
## Logged population size -0.10** -0.10**
## (0.05) (0.05)
## Electoral violence x Incumbent strength -0.33**
## (0.14)
## Constant -0.36*** -0.17 -0.26
## (0.04) (0.61) (0.58)
## ---------------------------------------------------------------------
## McFadden's Adjusted R2 -0.03 -0.05 -0.06
## Observations 205 205 205
## Akaike Inf. Crit. 286.31 294.49 296.03
## =====================================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
##### Controlling for voter turnout in 2020 ####
# Specify Model 1
model1 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model1, vcov = vcovHC(model1, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.049501 0.053306 0.9286 0.3531
## Electoral.Violence.Events -0.099410 0.020623 -4.8203 1.433e-06 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Specify model 2
model2 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events +
RDR.Vote.Share.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged +
Voter.Turnout.2020,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model2, vcov = vcovHC(model2, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.1802673 0.6589412 0.2736 0.784414
## Electoral.Violence.Events -0.0131026 0.0103050 -1.2715 0.203557
## RDR.Vote.Share.2010 0.3049467 0.1454795 2.0961 0.036069
## Electoral.Violence.Events.Spatial.Lag 0.0073089 0.0145401 0.5027 0.615192
## Electoral.Violence.Events.2011 -0.0114396 0.0056238 -2.0342 0.041936
## Number.of.Seats.2021 0.0257747 0.0614092 0.4197 0.674689
## Voter.Turnout.2016 1.7921289 0.4599409 3.8964 9.762e-05
## Poverty.Ratio 0.2377987 0.1573979 1.5108 0.130836
## Population.2014.Logged -0.1452281 0.0540838 -2.6852 0.007248
## Voter.Turnout.2020 0.2621384 0.1163134 2.2537 0.024214
##
## (Intercept)
## Electoral.Violence.Events
## RDR.Vote.Share.2010 *
## Electoral.Violence.Events.Spatial.Lag
## Electoral.Violence.Events.2011 *
## Number.of.Seats.2021
## Voter.Turnout.2016 ***
## Poverty.Ratio
## Population.2014.Logged **
## Voter.Turnout.2020 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Specify Model 3
model3 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events * RDR.Vote.Share.2010 +
RDR.Vote.Share.2010 +
Electoral.Violence.Events.Spatial.Lag +
Electoral.Violence.Events.2011 +
Number.of.Seats.2021 +
Voter.Turnout.2016 +
Poverty.Ratio +
Population.2014.Logged +
Voter.Turnout.2020,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model3, vcov = vcovHC(model3, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value
## (Intercept) -0.1682849 0.5520952 -0.3048
## Electoral.Violence.Events 0.0866906 0.0480191 1.8053
## RDR.Vote.Share.2010 0.4515705 0.1492710 3.0252
## Electoral.Violence.Events.Spatial.Lag 0.0077169 0.0136780 0.5642
## Electoral.Violence.Events.2011 -0.0109172 0.0075534 -1.4453
## Number.of.Seats.2021 0.0589168 0.0693651 0.8494
## Voter.Turnout.2016 1.8329705 0.3976622 4.6094
## Poverty.Ratio 0.2465800 0.1480577 1.6654
## Population.2014.Logged -0.1185535 0.0433762 -2.7331
## Voter.Turnout.2020 0.1898438 0.1125115 1.6873
## Electoral.Violence.Events:RDR.Vote.Share.2010 -0.5022035 0.2311327 -2.1728
## Pr(>|z|)
## (Intercept) 0.760510
## Electoral.Violence.Events 0.071022 .
## RDR.Vote.Share.2010 0.002485 **
## Electoral.Violence.Events.Spatial.Lag 0.572629
## Electoral.Violence.Events.2011 0.148366
## Number.of.Seats.2021 0.395675
## Voter.Turnout.2016 4.039e-06 ***
## Poverty.Ratio 0.095827 .
## Population.2014.Logged 0.006273 **
## Voter.Turnout.2020 0.091540 .
## Electoral.Violence.Events:RDR.Vote.Share.2010 0.029796 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Create lists of robust standard errors
robust_se1 <- sqrt(diag(vcovHC(model1, type = "HC")))
robust_se2 <- sqrt(diag(vcovHC(model2, type = "HC")))
robust_se3 <- sqrt(diag(vcovHC(model3, type = "HC")))
# Create lists of McFadden's Adjusted R2
mcfadden1 <- format(round(PseudoR2(model1, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden2 <- format(round(PseudoR2(model2, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden3 <- format(round(PseudoR2(model3, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
# Make regression table
stargazer(
model1,
model2,
model3,
title = "Controlling for voter turnout in 2020",
label = "tab:reg-turnout2020",
align = TRUE,
column.sep.width = "5pt",
no.space = TRUE,
omit.stat = c("LL", "ser", "f"),
se = list(robust_se1, robust_se2, robust_se3),
dep.var.labels = "Voter turnout",
digits = 2,
font.size = "footnotesize",
single.row = FALSE,
omit.table.layout = "ld",
covariate.labels = c(
"Electoral violence",
"Incumbent strength",
"Electoral violence (spatial lag)",
"Past electoral violence",
"Number of seats",
"Voter turnout (2016)",
"Poverty ratio",
"Logged population size",
"Voter turnout (2020)",
"Electoral violence x Incumbent strength"
),
add.lines = list(c("McFadden's Adjusted R2", mcfadden1, mcfadden2, mcfadden3)),
notes.append = FALSE,
star.cutoffs = c(.1, .05, .01),
type = "text",
out = "table_a13"
)
##
## Controlling for voter turnout in 2020
## =====================================================================
## (1) (2) (3)
## ---------------------------------------------------------------------
## Electoral violence -0.10*** -0.01 0.09*
## (0.02) (0.01) (0.05)
## Incumbent strength 0.30** 0.45***
## (0.15) (0.15)
## Electoral violence (spatial lag) 0.01 0.01
## (0.01) (0.01)
## Past electoral violence -0.01** -0.01
## (0.01) (0.01)
## Number of seats 0.03 0.06
## (0.06) (0.07)
## Voter turnout (2016) 1.79*** 1.83***
## (0.46) (0.40)
## Poverty ratio 0.24 0.25*
## (0.16) (0.15)
## Logged population size -0.15*** -0.12***
## (0.05) (0.04)
## Voter turnout (2020) 0.26** 0.19*
## (0.12) (0.11)
## Electoral violence x Incumbent strength -0.50**
## (0.23)
## Constant 0.05 0.18 -0.17
## (0.05) (0.66) (0.55)
## ---------------------------------------------------------------------
## McFadden's Adjusted R2 0.04 0.17 0.17
## Observations 205 188 188
## Akaike Inf. Crit. 268.73 212.29 212.21
## =====================================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
#### Parsimonious models ####
# Specify Model 1
model1 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events * RDR.Vote.Share.2010,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model1, vcov = vcovHC(model1, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value
## (Intercept) -0.411697 0.061480 -6.6964
## Electoral.Violence.Events 0.062508 0.021127 2.9586
## RDR.Vote.Share.2010 1.131759 0.151072 7.4915
## Electoral.Violence.Events:RDR.Vote.Share.2010 -0.678018 0.104598 -6.4821
## Pr(>|z|)
## (Intercept) 2.136e-11 ***
## Electoral.Violence.Events 0.00309 **
## RDR.Vote.Share.2010 6.807e-14 ***
## Electoral.Violence.Events:RDR.Vote.Share.2010 9.044e-11 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Specify model 2
model2 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events * RDR.Vote.Share.2010 +
RDR.Vote.Share.2010 +
Voter.Turnout.2016,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model2, vcov = vcovHC(model2, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value
## (Intercept) -1.293942 0.135239 -9.5678
## Electoral.Violence.Events 0.043899 0.026472 1.6583
## RDR.Vote.Share.2010 0.446430 0.150617 2.9640
## Voter.Turnout.2016 2.375395 0.314300 7.5577
## Electoral.Violence.Events:RDR.Vote.Share.2010 -0.401944 0.172645 -2.3282
## Pr(>|z|)
## (Intercept) < 2.2e-16 ***
## Electoral.Violence.Events 0.097251 .
## RDR.Vote.Share.2010 0.003037 **
## Voter.Turnout.2016 4.102e-14 ***
## Electoral.Violence.Events:RDR.Vote.Share.2010 0.019904 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Specify Model 3
model3 <- glm(
Voter.Turnout.2021 ~
Electoral.Violence.Events * RDR.Vote.Share.2010 +
RDR.Vote.Share.2010 +
Population.2014.Logged,
data = df,
family = binomial(link = logit)
)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
# Calculate heteroscedasticity-consistent standard errors
coeftest(model3, vcov = vcovHC(model3, type = "HC"))
##
## z test of coefficients:
##
## Estimate Std. Error z value
## (Intercept) 2.401473 0.304151 7.8957
## Electoral.Violence.Events 0.050418 0.017162 2.9378
## RDR.Vote.Share.2010 1.013926 0.144839 7.0004
## Population.2014.Logged -0.272672 0.029116 -9.3649
## Electoral.Violence.Events:RDR.Vote.Share.2010 -0.417545 0.093329 -4.4739
## Pr(>|z|)
## (Intercept) 2.888e-15 ***
## Electoral.Violence.Events 0.003305 **
## RDR.Vote.Share.2010 2.553e-12 ***
## Population.2014.Logged < 2.2e-16 ***
## Electoral.Violence.Events:RDR.Vote.Share.2010 7.681e-06 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Create lists of robust standard errors
robust_se1 <- sqrt(diag(vcovHC(model1, type = "HC")))
robust_se2 <- sqrt(diag(vcovHC(model2, type = "HC")))
robust_se3 <- sqrt(diag(vcovHC(model3, type = "HC")))
# Create lists of McFadden's Adjusted R2
mcfadden1 <- format(round(PseudoR2(model1, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden2 <- format(round(PseudoR2(model2, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
mcfadden3 <- format(round(PseudoR2(model3, c("McFaddenAdj")), 2), nsmall = 2)
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!
## Warning in eval(family$initialize): number of items to replace is not a multiple
## of replacement length
# Make regression table
stargazer(
model1,
model2,
model3,
title = "Parsimonious models",
label = "tab:reg-pars",
align = TRUE,
column.sep.width = "5pt",
no.space = TRUE,
omit.stat = c("LL", "ser", "f"),
se = list(robust_se1, robust_se2, robust_se3),
dep.var.labels = "Voter turnout",
digits = 2,
font.size = "footnotesize",
single.row = FALSE,
omit.table.layout = "ld",
covariate.labels = c(
"Electoral violence",
"Incumbent strength",
"Past voter turnout",
"Logged population size",
"Electoral violence x Incumbent strength"
),
add.lines = list(c("McFadden's Adjusted R2", mcfadden1, mcfadden2, mcfadden3)),
notes.append = FALSE,
star.cutoffs = c(.1, .05, .01),
type = "text",
out = "table_a14"
)
##
## Parsimonious models
## =====================================================================
## (1) (2) (3)
## ---------------------------------------------------------------------
## Electoral violence 0.06*** 0.04* 0.05***
## (0.02) (0.03) (0.02)
## Incumbent strength 1.13*** 0.45*** 1.01***
## (0.15) (0.15) (0.14)
## Past voter turnout 2.38***
## (0.31)
## Logged population size -0.27***
## (0.03)
## Electoral violence x Incumbent strength -0.68*** -0.40** -0.42***
## (0.10) (0.17) (0.09)
## Constant -0.41*** -1.29*** 2.40***
## (0.06) (0.14) (0.30)
## ---------------------------------------------------------------------
## McFadden's Adjusted R2 0.12 0.20 0.17
## Observations 205 205 205
## Akaike Inf. Crit. 245.09 224.32 233.11
## =====================================================================
## Note: *p<0.1; **p<0.05; ***p<0.01
#### Make histograms of all variables ####
# Make visualization theme for histograms
histo_theme <-
theme(
plot.margin = unit(c(1,1,1,1), "cm"),
axis.title.y = element_text(margin = margin (t = 0, r = 10, b = 0, l = 0), size = 22),
axis.title.x = element_text(margin = margin (t = 10, r = 0, b = 0, l = 0), size = 22),
axis.text.x = element_text(size = 16),
axis.text.y = element_text(size = 16),
legend.position = "bottom"
)
# RDR vote share
ggplot() +
geom_histogram(
data = df,
aes(x = RDR.Vote.Share.2010),
stat = "bin"
) +
labs(
y = "Number of observations",
x = "RDR vote share 2010",
title = NULL
) +
histo_theme
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

ggsave("histo_rdr_vote_share_2010.png", height = 15, width = 22, units = "cm")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
# Electoral violence
ggplot() +
geom_histogram(
data = df,
aes(x = Electoral.Violence.Events),
stat = "bin"
) +
labs(
y = "Number of observations",
x = "Electoral violence",
title = NULL
) +
histo_theme
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

ggsave("histo_electoral_violence.png", height = 15, width = 22, units = "cm")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
# Incumbent violence
ggplot() +
geom_histogram(
data = df,
aes(x = Electoral.Violence.Events.Incumbent),
stat = "bin"
) +
labs(
y = "Number of observations",
x = "Incumbent violence",
title = NULL
) +
histo_theme
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

ggsave("histo_electoral_violence_incumbent.png", height = 15, width = 22, units = "cm")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
# Opposition violence
ggplot() +
geom_histogram(
data = df,
aes(x = Electoral.Violence.Events.Opposition),
stat = "bin"
) +
labs(
y = "Number of observations",
x = "Opposition violence",
title = NULL
) +
histo_theme
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

ggsave("histo_electoral_violence_opposition.png", height = 15, width = 22, units = "cm")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
# Electoral violence (spatial lag)
ggplot() +
geom_histogram(
data = df,
aes(x = Electoral.Violence.Events.Spatial.Lag),
stat = "bin"
) +
labs(
y = "Number of observations",
x = "Electoral violence (spatial lag)",
title = NULL
) +
histo_theme
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

ggsave("histo_electoral_violence_lag.png", height = 15, width = 22, units = "cm")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
# Electoral violence (2011)
ggplot() +
geom_histogram(
data = df,
aes(x = Electoral.Violence.Events.2011),
stat = "bin"
) +
labs(
y = "Number of observations",
x = "Electoral violence (2011)",
title = NULL
) +
histo_theme
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

ggsave("histo_electoral_violence_2011.png", height = 15, width = 22, units = "cm")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
# Number of seats
ggplot() +
geom_histogram(
data = df,
aes(x = Number.of.Seats.2021),
stat = "bin"
) +
labs(
y = "Number of observations",
x = "Number of seats",
title = NULL
) +
histo_theme
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

ggsave("histo_number_of_seats.png", height = 15, width = 22, units = "cm")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
# Voter turnout (2016)
ggplot() +
geom_histogram(
data = df,
aes(x = Voter.Turnout.2016),
stat = "bin"
) +
labs(
y = "Number of observations",
x = "Voter turnout (2016)",
title = NULL
) +
histo_theme
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

ggsave("histo_voter_turnout_2016.png", height = 15, width = 22, units = "cm")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
# Voter turnout (2021)
ggplot() +
geom_histogram(
data = df,
aes(x = Voter.Turnout.2021),
stat = "bin"
) +
labs(
y = "Number of observations",
x = "Voter turnout (2016)",
title = NULL
) +
histo_theme
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

ggsave("histo_voter_turnout.png", height = 15, width = 22, units = "cm")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
# Poverty ratio
ggplot() +
geom_histogram(
data = df,
aes(x = Poverty.Ratio),
stat = "bin"
) +
labs(
y = "Number of observations",
x = "Poverty Ratio",
title = NULL
) +
histo_theme
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

ggsave("histo_poverty_ratio.png", height = 15, width = 22, units = "cm")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
# Logged population size
ggplot() +
geom_histogram(
data = df,
aes(x = Population.2014.Logged),
stat = "bin"
) +
labs(
y = "Number of observations",
x = "Logged population size",
title = NULL
) +
histo_theme
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

ggsave("histo_population_size.png", height = 15, width = 22, units = "cm")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
#### Diagnosing the interaction effect ####
binning <- interflex(
Y = "Voter.Turnout.2021",
D = "Electoral.Violence.Events",
X = "RDR.Vote.Share.2010",
Z = c(
"Electoral.Violence.Events.Spatial.Lag",
"Electoral.Violence.Events.2011",
"Number.of.Seats.2021",
"Voter.Turnout.2016",
"Poverty.Ratio",
"Population.2014.Logged"
),
data = df,
estimator = "binning",
vcov.type = "robust",
main = "Marginal Effects",
ylim = c(-5, 0),
figure = TRUE,
nbins = 3
)
plot(
binning,
xlab = "Incumbent strength (%)",
ylab = "Marginal effect of electoral violence on voter turnout",
file = "figure_a4_panel_upper.jpg"
)

kernel <- interflex(
Y = "Voter.Turnout.2021",
D = "Electoral.Violence.Events",
X = "RDR.Vote.Share.2010",
Z = c(
"Electoral.Violence.Events.Spatial.Lag",
"Electoral.Violence.Events.2011",
"Number.of.Seats.2021",
"Voter.Turnout.2016",
"Poverty.Ratio",
"Population.2014.Logged"
),
data = df,
nboots = 200,
estimator = "kernel",
vcov.type = "robust",
main = "Marginal Effects"
)
## Cross-validating bandwidth ...
## Parallel computing with 4 cores...
## Optimal bw=0.2047.
## Number of evaluation points:50
## Parallel computing with 4 cores...
##
plot(
kernel,
xlab = "Incumbent strength (%)",
ylab = "Marginal effect of electoral violence on voter turnout",
file = "figure_a4_panel_lower.jpg"
)
