library(bt) source('utils.R') library('lattice') trellis.par.set(col.whitebg()) library('grid') # This is the seat containing the ward (or at least, my best guess) seats <- read.csv('wards.csv') seats <- as.bt(seats[,c('ward','oldseat','people')], value='people') seats[] <- ifelse(is.na(seats),0,seats) wards <- seats$ward st <- seats$oldseat mainseat <- ifelse(seats[oldseat=st[1],ward=wards]>seats[oldseat=st[2],ward=wards], st[1],st[2]) names(mainseat) <- wards mainseat # This is the swing in each seat national <- read.csv('national.csv') national <- as.bt(national[,c('year','seat','party','votes')], value='votes') natswing <- national[year=2005,]/national[year=2001,] natswing$year <- NULL natswing <- natswing[party=c('Conservative','Green','Labour','Liberal Democrat'),] natswing natswing # Read in the 2002 results local2002 <- read.csv('local2002.csv') local2002$candidate <- paste(as.character(local2002$forename), as.character(local2002$name)) local2002$name <- NULL local2002$forename <- NULL # Apply swing for (i in 1:nrow(local2002)) local2002[i,'swing'] <- natswing[party=as.character(local2002[i,'party']), seat=mainseat[local2002[i,'ward']]] [] local <- local2002[!is.na(local2002$swing),] local$votes2 <- local$votes * local$swing local$party <- factor(sapply(strsplit(as.character(local$party),' '), paste, collapse='')) res <- by(local, INDICES=list(ward=local$ward), FUN=function(df) as.character(df[order(-df$votes2),][1:3,]$party)) df <- data.frame(ward=names(res)) df$counc1 <- sapply(res, function(x) x[1]) df$counc2 <- sapply(res, function(x) x[2]) df$counc3 <- sapply(res, function(x) x[3]) newseats <- reshape(df, direction='long', idvar='ward', varying=list(c('counc1','counc2','counc3')), v.names='party', timevar='counc') row.names(newseats) <- 1:nrow(newseats) newseats <- newseats[order(newseats$ward),] newseats$party <- factor(newseats$party) res <- by(local, INDICES=list(ward=local$ward), FUN=function(df) as.character(df[order(-df$votes),][1:3,]$party)) df <- data.frame(ward=names(res)) df$counc1 <- sapply(res, function(x) x[1]) df$counc2 <- sapply(res, function(x) x[2]) df$counc3 <- sapply(res, function(x) x[3]) oldseats <- reshape(df, direction='long', idvar='ward', varying=list(c('counc1','counc2','counc3')), v.names='party', timevar='counc') row.names(oldseats) <- 1:nrow(oldseats) oldseats <- oldseats[order(oldseats$ward),] oldseats$party <- factor(oldseats$party) xtabs(~ward + party, data=newseats) xtabs(~party, data=oldseats) xtabs(~ward + party, data=oldseats) xtabs(~party, data=oldseats) seats <- rbind( cbind(oldseats,year=2002), cbind(newseats,year=2006)) xtabs(~party + year, data=seats) xtabs(~ward + party, data=seats, subset= year==2006) dr <- 2*pi/360 dirs <- matrix(c( cos(30*dr),-sin(30*dr), -cos(30*dr),-sin(30*dr), 0,1 ),nrow=2,byrow=FALSE) share1ToX <- function(votes) sum(c(1,0) %*% (dirs %*% diag(log(votes)))) share1ToY <- function(votes) sum(c(0,1) %*% (dirs %*% diag(log(votes)))) shareToXY <- function(...) { votes1 <- list(...)[[1]] votes2 <- list(...)[[2]] votes3 <- list(...)[[3]] df <- data.frame(v1=votes1,v2=votes2,v3=votes3) df <- as.matrix(df) list(x=sapply(1:nrow(df), function(i) share1ToX(df[i,])), y=sapply(1:nrow(df), function(i) share1ToY(df[i,]))) } # I want: # a data frame which lists, for each consituency, # total, new total for each party # another data frame which lists, for each constituency, # top four candidates (old), top four candidates (new) totvotes <- aggregate(local[,c('votes','votes2')], by=list(ward=local$ward, party=local$party), FUN=sum) totvotes <- reshape(totvotes, direction='long', idvar=c('ward','party'), varying=list(c('votes','votes2')), v.names='votes', timevar='year', times=c(2002,2006)) totvotes <- reshape(totvotes, direction='wide', idvar=c('ward','year'), v.names='votes', timevar='party') counc.old <- by(local, INDICES=list(ward=local$ward), FUN=function(df) as.character(df[order(-df$votes),][1:4,]$party)) counc.old <- do.call('rbind',counc.old) counc.new <- by(local, INDICES=list(ward=local$ward), FUN=function(df) as.character(df[order(-df$votes2),][1:4,]$party)) counc.new <- do.call('rbind',counc.new) counc <- rbind(cbind(counc.old,year='2002'),cbind(counc.new,year='2006')) counc <- cbind(counc,ward=row.names(counc)) row.names(counc) <- NULL counc <- data.frame(counc) grid.arc <- function(x,y,r,thmin,thmax,...) { th <- seq(thmin,thmax,(thmax-thmin)/360) px <- x+r*c(0,cos(th)) py <- y+r*c(0,sin(th)) grid.polygon(px,py,...) } partycols.default <- c('Labour'='red', 'LiberalDemocrat'='yellow', 'Green'='green','Conservative'='blue') partycols.light <- c('Labour'='pink2', 'LiberalDemocrat'='khaki', 'Green'='green', 'Conservative'='lightblue') plotWard <- function(x,y,name,counc,partycols=partycols.default) { partycols <- partycols[counc] grid.arc(x=x,y=y,r=.1, thmin=pi/2-2/3*pi,thmax=pi/2, default.units='native',gp=gpar(fill=partycols[1])) grid.arc(x=x,y=y,r=.1, thmin=pi/2,thmax=pi/2+2/3*pi, default.units='native',gp=gpar(fill=partycols[2])) grid.arc(x=x,y=y,r=.1, thmin=pi/2+2/3*pi,thmax=pi/2+4/3*pi, default.units='native',gp=gpar(fill=partycols[3])) grid.circle(x=x,y=y,r=.04, default.units='native',gp=gpar(fill=partycols[4])) grid.text(x=x+.1,y=y,label=name, default.units='native',hjust=0,gp=gpar(cex=.5)) } wantparties <- c('Labour','Conservative','LiberalDemocrat')[c(1,3,2)] xyplot(1~1, panel=function(...) { bd <- shareToXY(10,1:89,89:1); panel.xyplot(bd$x,bd$y, type='l',col='grey') bd <- shareToXY(1:89,10,89:1); panel.xyplot(bd$x,bd$y, type='l',col='grey') bd <- shareToXY(1:89,89:1,10); panel.xyplot(bd$x,bd$y, type='l',col='grey') bd <- shareToXY(c(1,100),c(1,100),1); panel.xyplot(bd$x,bd$y, type='l',col='grey') bd <- shareToXY(1,c(1,100),c(1,100)); panel.xyplot(bd$x,bd$y, type='l',col='grey') bd <- shareToXY(c(1,100),1,c(1,100)); panel.xyplot(bd$x,bd$y, type='l',col='grey') bd <- shareToXY(10,10,80); ltext(bd$x,bd$y,'Cons',fontface=2) bd <- shareToXY(10,80,10); ltext(bd$x,bd$y,'LibDem',fontface=2) bd <- shareToXY(80,10,10); ltext(bd$x,bd$y,'Lab',fontface=2) wards <- levels(totvotes$ward) for (ward in wards) { wantcols <- paste('votes',wantparties,sep='.') xy1 <- totvotes[totvotes$ward==ward & totvotes$year==2002,wantcols] xy1 <- do.call('shareToXY',xy1) xy2 <- totvotes[totvotes$ward==ward & totvotes$year==2006,wantcols] xy2 <- do.call('shareToXY',xy2) councw2 <- counc[counc$ward==ward & counc$year==2006,c('V1','V2','V3','V4')] councw2 <- as.matrix(councw2)[1,] plotWard(xy2$x,xy2$y,'',councw2, partycols=partycols.light) larrows(xy1$x,xy1$y,xy2$x,xy2$y,length=.1) } for (ward in wards) { wantcols <- paste('votes',wantparties,sep='.') xy1 <- totvotes[totvotes$ward==ward & totvotes$year==2002,wantcols] xy1 <- do.call('shareToXY',xy1) councw1 <- counc[counc$ward==ward & counc$year==2002,c('V1','V2','V3','V4')] councw1 <- as.matrix(councw1)[1,] plotWard(xy1$x,xy1$y,ward,councw1) } }, xlim=c(-2,2),ylim=c(-1.6,2.2), scales=list(draw=FALSE,col='white'),xlab='',ylab='') res <- counc[counc$ward=='Kentish Town' & counc$year==2002, c('V1','V2','V3','V4')] as.matrix(res)[1,]