Last active
April 24, 2017 20:45
-
-
Save chrishanretty/be9cb5a2df9b3e8142d3df22678a0763 to your computer and use it in GitHub Desktop.
Analysis of swings in Conservative and Labour-held seats, BES data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library(foreign) ## for data import | |
library(dplyr) ## for chaining ops together | |
library(ggplot2) ## for plotting | |
library(reshape2) ## for reshaping | |
library(hrbrthemes) ## for pretty pictures | |
library(survey) ## for... uh, survey data | |
party.colours <- c("#0087DC","#D50000","#FDBB30","#FFFF00","#008142","#99CC33","#70147A","#DDDDDD") | |
bes <- read.spss("~/Dropbox/2017-forecasting/data/individual/BES2015_W10_Panel_v0.3.sav") | |
res <- read.csv("~/Dropbox/2017-forecasting/data/constituency/ge2015_results.csv") | |
bes <- merge(bes, res[,c("pano", "Winner15")], | |
all.x = TRUE, | |
all.y = FALSE, | |
by = "pano") | |
### Tidy up the VI vars so we have the right labels | |
### | |
bes$generalElectionVoteW6 <- car:::recode(as.character(bes$generalElectionVoteW6), | |
"'Labour'='Labour'; | |
'Conservative'='Conservatives'; | |
'Liberal Democrat'= 'Liberal Democrats'; | |
'Scottish National Party (SNP)'= 'SNP'; | |
'Plaid Cymru'='Plaid Cymru'; | |
'Green Party'='Greens'; | |
'United Kingdom Independence Party (UKIP)'='UKIP'; | |
else = NA") | |
bes$vi_ge <- factor(bes$generalElectionVoteW6, | |
levels = c("Conservatives", "Labour", | |
"Liberal Democrats", "SNP", | |
"Plaid Cymru", "Greens", | |
"UKIP", "Other"), | |
ordered = TRUE) | |
bes$generalElectionVoteW10 <- car:::recode(as.character(bes$generalElectionVoteW10), | |
"'Labour'='Labour'; | |
'Conservative'='Conservatives'; | |
'Liberal Democrat'= 'Liberal Democrats'; | |
'Scottish National Party (SNP)'= 'SNP'; | |
'Plaid Cymru'='Plaid Cymru'; | |
'Green Party'='Greens'; | |
'United Kingdom Independence Party (UKIP)'='UKIP'; | |
else = NA") | |
bes$vi <- factor(bes$generalElectionVoteW10, | |
levels = c("Conservatives", "Labour", | |
"Liberal Democrats", "SNP", | |
"Plaid Cymru", "Greens", | |
"UKIP", "Other"), | |
ordered = TRUE) | |
### Only use certain variables | |
bes <- bes[,c("pano", "vi", "Winner15", "vi_ge","wt_full_W9")] | |
### Restrict to those for whom we know constituency | |
bes <- subset(bes, !is.na(pano)) | |
### Restrict to those with a weight for the post-election wave | |
bes <- subset(bes, !is.na(wt_full_W9)) | |
mySvy <- svydesign(ids = ~1, weights = bes$wt_full_W9, data = bes) | |
### Table of VI currently | |
svytable(~vi, mySvy) / sum(svytable(~vi, mySvy)) | |
### Table of Conservative-held seats | |
vitab <- svytable(~Winner15+vi, mySvy) | |
nRespondents <- rowSums(vitab) | |
vitab.pct <- vitab / nRespondents | |
vitab.m <- melt(vitab.pct) | |
### Merge this with the known results from last time | |
res.m <- melt(res[,c("Winner15", "TotalVote15", "Con15", "Lab15", "LD15", "SNP15", | |
"PC15", "UKIP15", "Green15", "Other15")], | |
id.vars = c("Winner15", "TotalVote15")) | |
res.m$votes <- res.m$value / 100 * res.m$TotalVote15 | |
res.m <- res.m %>% | |
group_by(Winner15) %>% | |
mutate(totalVotes = sum(unique(TotalVote15))) %>% | |
group_by(Winner15, variable) %>% | |
summarize(known_share = sum(votes, na.rm = TRUE) / unique(totalVotes)) | |
### Change the labelling | |
res.m$vi <- car::recode(res.m$variable, | |
"'Con15'='Conservatives'; 'Lab15'='Labour'; | |
'LD15'='Liberal Democrats';'SNP15'='SNP';'PC15'='Plaid Cymru'; | |
'Green15'='Greens';'UKIP15'='UKIP'; else ='Other'") | |
vitab.m <- merge(vitab.m, res.m, | |
by = c("Winner15", "vi"), | |
all = TRUE) | |
vitab.m$swing <- vitab.m$value - vitab.m$known_share | |
vitab.m$win_label <- as.character(vitab.m$Winner15) | |
vitab.m$win_label <- sub("Scottish National Party", "SNP", vitab.m$win_label) | |
vitab.m$win_label <- paste0(vitab.m$win_label, | |
"-held seats") | |
my.ylims <- c(-0.1, .125) | |
p1.df <- subset(vitab.m, | |
vi == "Conservatives" & | |
Winner15 %in% c("Conservative", "Labour", "Liberal Democrat", | |
"Scottish National Party")) | |
p1 <- ggplot(p1.df, | |
aes(x = win_label, y = swing)) + | |
geom_bar(stat = "identity", width = 0.6, fill = party.colours[1]) + | |
geom_hline(yintercept = 0) + | |
scale_x_discrete("") + | |
scale_y_continuous("Change", labels = scales::percent, limits = my.ylims) + | |
coord_flip() + | |
theme_minimal() + | |
theme_ipsum_rc() + | |
labs(title = "The Conservatives are up in seats they don't already hold", | |
subtitle = "Source: BES wave 10") | |
p2.df <- subset(vitab.m, | |
vi == "Labour" & | |
Winner15 %in% c("Conservative", "Labour", "Liberal Democrat", | |
"Scottish National Party")) | |
p2 <- ggplot(p2.df, | |
aes(x = win_label, y = swing)) + | |
geom_bar(stat = "identity", width = 0.6, fill = party.colours[2]) + | |
geom_hline(yintercept = 0) + | |
scale_x_discrete("") + | |
scale_y_continuous("Change", labels = scales::percent, limits = my.ylims) + | |
coord_flip() + | |
theme_minimal() + | |
theme_ipsum_rc() + | |
labs(title = "Labour is going backwards in former heartlands", | |
subtitle = "Source: BES wave 10") | |
p3.df <- subset(vitab.m, | |
vi == "Liberal Democrats" & | |
Winner15 %in% c("Conservative", "Labour", "Liberal Democrat", | |
"Scottish National Party")) | |
p3 <- ggplot(p3.df, | |
aes(x = win_label, y = swing)) + | |
geom_bar(stat = "identity", width = 0.6, fill = party.colours[3]) + | |
geom_hline(yintercept = 0) + | |
scale_x_discrete("") + | |
scale_y_continuous("Change", labels = scales::percent, limits = my.ylims) + | |
coord_flip() + | |
theme_minimal() + | |
theme_ipsum_rc() + | |
labs(title = "The Lib Dem vote is spreading out...", | |
subtitle = "Source: BES wave 10") | |
p4.df <- subset(vitab.m, | |
vi == "UKIP" & | |
Winner15 %in% c("Conservative", "Labour", "Liberal Democrat", | |
"Scottish National Party")) | |
p4 <- ggplot(p4.df, | |
aes(x = win_label, y = swing)) + | |
geom_bar(stat = "identity", width = 0.6, fill = party.colours[7]) + | |
geom_hline(yintercept = 0) + | |
scale_x_discrete("") + | |
scale_y_continuous("Change", labels = scales::percent, limits = my.ylims) + | |
coord_flip() + | |
theme_minimal() + | |
theme_ipsum_rc() + | |
labs(title = "UKIP is falling back everywhere but Scotland", | |
subtitle = "Source: BES wave 10") | |
png(file = "p1.png", width = 600, height = 600) | |
print(p1) | |
dev.off() | |
png(file = "p2.png", width = 600, height = 600) | |
print(p2) | |
dev.off() | |
png(file = "p3.png", width = 600, height = 600) | |
print(p3) | |
dev.off() | |
png(file = "p4.png", width = 600, height = 600) | |
print(p4) | |
dev.off() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment