Skip to content

Instantly share code, notes, and snippets.

@chrishanretty
Created December 22, 2017 07:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrishanretty/9ccba708078f04b86372ee8c3a376bbf to your computer and use it in GitHub Desktop.
Save chrishanretty/9ccba708078f04b86372ee8c3a376bbf to your computer and use it in GitHub Desktop.
Ministerial exits from government
### Load libraries
library(tidyverse)
library(countrycode)
library(hrbrthemes)
### Download the files if they do not exist already
govf <- "Seki-Williams Governments--Version 2.0.csv"
minf <- "Seki-Williams Ministers--Version 2.0.csv"
if (!file.exists(govf)) {
download.file("http://faculty.missouri.edu/williamslaro/Seki-Williams%20Governments--Version%202.0.csv",
destfile = govf)
}
if (!file.exists(minf)) {
download.file("http://faculty.missouri.edu/williamslaro/Seki-Williams%20Ministers--Version%202.0.csv",
destfile = minf)
}
### Read in the files
gov <- read.csv(govf)
min <- read.csv(minf)
### Handle dates
gov <- gov %>%
mutate(gstart = paste(startday, startmonth, startyear,
sep = "/"),
gstart = as.Date(gstart,
format = "%d/%m/%Y"),
gend = gstart + duration)
min <- min %>%
mutate(mstart = paste(mstart_day, mstart_month, mstart_year,
sep = "/"),
mstart = as.Date(mstart,
format = "%d/%m/%Y"),
mend = paste(mend_day, mend_month, mend_year,
sep = "/"),
mend = as.Date(mend,
format = "%d/%m/%Y"))
### Handle countries
gov$iso3c <- countrycode(gov$country,
"country.name",
"iso3c")
min$iso3c <- countrycode(min$ccode,
"country.name",
"iso3c")
### Select only some variables
gov <- gov %>%
select(iso3c, govtseq, prime, gstart, gend)
min <- min %>%
select(iso3c, govtseq, minister_id, mstart, mend)
### Merge
min <- merge(min, gov,
all.x = TRUE,
all.y = FALSE)
### Remove those spells which terminated at the same time as the government
min <- min %>%
filter(mend < gend)
### Convert multiple ministerial spells or multiple portfolios to a
### single entry
### Case (1): two spells w/ duplicated start, end-dates
### (b/c multiple portfolios)
### select one unique row
nrow(min)
min <- min %>%
group_by(iso3c, govtseq, prime, minister_id, gstart, gend) %>%
distinct(mstart, mend)
nrow(min)
### Case (2): two spells w/ duplicated end-dates
### (b/c multiple nonconsecutive portfolios)
### select row with longer span
nrow(min)
min <- min %>%
group_by(iso3c, govtseq, prime, minister_id, mend) %>%
filter(mstart == min(mstart))
nrow(min)
### Case (3): two spells w/ duplicated start-dates
### (b/c multiple nonconsecutive portfolios)
### select row with longer span
nrow(min)
min <- min %>%
group_by(iso3c, govtseq, prime, minister_id, mstart) %>%
filter(mend == max(mend))
nrow(min)
### Case (3): two spells which overlap
### What to do? First, check for continuity
### I'll take any spell longer than a week as evidence of a break
checkContinuous <- function(start, end) {
if (any(is.na(end))) {
return(NA)
}
if (any(start > end)) {
return(NA)
}
outseq <- lapply(1:length(start), function(i) {
seq.Date(from = start[i], to = end[i], by = 1)
})
outseq <- sort(unique(do.call("c", outseq)))
diffs <- diff(outseq)
isBroken <- any(diff(outseq) > 7)
return(!isBroken)
}
min <- min %>%
group_by(iso3c, govtseq, minister_id) %>%
arrange(mstart) %>%
mutate(contig = checkContinuous(mstart, mend))
### Deal with contiguous and non-contiguous separately
### Treat non-contiguous as though they were all non-overlapping
min_a <- min %>%
filter(contig) %>%
group_by(iso3c, govtseq, prime, minister_id, gstart, gend) %>%
summarize(mstart = min(mstart),
mend = max(mend))
min_b <- min %>%
filter(!contig)
min <- merge(min_a, min_b, all = TRUE)
rm(min_a, min_b)
plot.df <- min %>%
select(iso3c, govtseq, prime, mend, gstart, gend) %>%
group_by(iso3c, govtseq) %>%
arrange(mend) %>%
mutate(tally = 1:n(),
daysAfter = as.numeric(mend - gstart)) %>%
group_by(iso3c, govtseq) %>%
filter(daysAfter != max(daysAfter))
### Add on a zero row
addon <- subset(plot.df, tally == 1)
addon$mend <- addon$gstart
addon$tally <- 0
addon$daysAfter <- 0
plot.df <- rbind(plot.df, addon)
### Add on the May cabinet
maydf <- data.frame(iso3c = "GBR",
prime = "May",
govtseq = 999,
tally = 0:3,
mend = as.Date(c("2017-06-11",
"2017-11-01",
"2017-11-08",
"2017-12-20")),
gstart = as.Date("2017-06-11"))
maydf$daysAfter <- as.numeric(maydf$mend - maydf$gstart)
plot.df <- merge(plot.df, maydf, all = TRUE)
### Create a single value for each day
plot.df <- plot.df %>%
group_by(iso3c, govtseq, prime, gstart, gend, daysAfter) %>%
summarize(tally = max(tally))
ann.df <- plot.df %>%
group_by(iso3c, govtseq, prime, gstart, gend) %>%
summarize(tally = max(tally),
daysAfter = max(daysAfter)) %>%
filter(tally > 17 | tally == 15 & daysAfter < 30) %>%
mutate(label = paste0(countrycode(iso3c, "iso3c", "country.name"),
"\n",
prime,
"\n(",
format(gstart, "%Y"),
"-",
format(gend, "%y"),
")")) %>%
arrange(daysAfter)
ann.df$adj <- c(1, rep(0, nrow(ann.df) - 1))
p <- ggplot(plot.df, aes(x = daysAfter, y = tally,
group = interaction(iso3c, govtseq))) +
geom_line(colour = "#99999977") +
geom_point(data = subset(plot.df, govtseq == 999 & tally == 3),
color = 'red') +
geom_line(data = subset(plot.df, govtseq == 999),
color = 'red') +
geom_point(data = ann.df, color = "#99999977" ) +
scale_x_continuous("Days after government formed") +
scale_y_continuous("Numbers of government exits") +
labs(title = "Ministerial exits, all governments 1990 to 2014",
subtitle = "Second May cabinet highlighted in red",
caption = "Data: Seki and Williams (2014), 'Updating the Party Government Data Set'. Electoral Studies.") +
geom_text(data = ann.df,
aes(label = label, adj = adj),
nudge_x = c(0, 0, 20, 0)) +
theme_ipsum_rc()
ggsave(p, file = "p.png", width = 12, height = 10)
#
summary.df <- plot.df %>%
group_by(iso3c, govtseq) %>%
filter(tally == max(tally)) %>%
mutate(rate = daysAfter / tally) %>%
arrange(rate)
summary.df$durat <- as.numeric(summary.df$gend - summary.df$gstart)
summary(lm(log1p(durat) ~ rate, data = summary.df))
with(summary.df, cor(rate,
as.numeric(gend - gstart),
use = "pairwise"))
which(summary.df$govtseq == 999)
ann.df <- plot.df %>%
filter(iso3c == "GBR") %>%
group_by(iso3c, govtseq, prime, gstart, gend) %>%
summarize(tally = max(tally),
daysAfter = max(daysAfter)) %>%
mutate(label = paste0(prime,
"\n(",
format(gstart, "%Y"),
"-",
format(gend, "%y"),
")")) %>%
arrange(daysAfter)
p3 <- ggplot(subset(plot.df, iso3c == "GBR"),
aes(x = daysAfter, y = tally,
group = interaction(iso3c, govtseq))) +
geom_point(data = ann.df, color = "#99999999") +
geom_point(data = subset(ann.df, govtseq == 999), color = "red") +
geom_text(data = ann.df, aes(label = label), adj = 0, nudge_x = 2) +
geom_line(colour = "#99999999") +
geom_line(data = subset(plot.df, govtseq == 999),
color = 'red') +
scale_x_continuous("Days after government formed") +
scale_y_continuous("Numbers of ministers moved, fired, resigned, or dead") +
labs(title = "Ministerial replacements, UK governments Major to Brown",
subtitle = "Second May cabinet highlighted in red",
caption = "Data: Seki and Williams (2014), 'Updating the Party Government Data Set'. Electoral Studies.") +
theme_ipsum_rc()
ggsave(p3, file = "p3.png", width = 12, height = 10)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment