Simulating the impact of changing electoral rules in Brazil

A few weeks ago, I and two colleagues published an op-ed at Folha de São Paulo, Brazil’s  biggest newspaper, criticizing the ‘distritão’ (translates as ‘big district’) proposal. Using simple simulations, we argued that the proposal would reinforce the power of incumbent parties and incentivize even more campaign spending by candidates, which is not exactly what Brazil needs right now. Fortunately, due to remarkable opposition in the press and the general public, the ‘distritão’ proposal was eventually rejected by Congress.

Here I share the code I used to run the simulation and some graphs we can use to compare the party composition of Brazil’s Chamber of Deputies and local Legislative Assemblies under the two different systems. Long story short, the ‘distritão’ system rank-orders all the candidates in a state according to their total vote share, regardless of votes in their parties. The first ‘n’ candidates in a state will be elected. ‘N’ is the amount of seats each state has in the national Chamber of Deputies. I used this rule of the game to run the simulation, as explained in the next paragraphs.

We start by finding the candidates elected in the current system. The dataset ‘dep_fed14.csv’ used below shows the electoral results of the 2014 national elections and can be easily downloaded at Brazil’s Electoral Court website.

d <- read.csv("dep_fed14.csv", colClasses = "character")

##Find elected candidates in the current system:
d.elect <- d[which(d$resultado_cod %in% c("4", "3")), ]

#Find amount of elected candidates by party

part1 <- data.frame(table(d.elect$partido_sig))
part1 <- arrange(part1, desc(Freq))
colnames(part1) <- c("party", "seats")


Now we move on to simulate who would be elected using the proposed ‘distritão’ rule, as explained in the second paragraph above: rank-order candidates according to vote share, select the first ‘n’ candidates. There is an obvious caveat to this simulation: while we run it using data for the 2014 election as it was, the campaign dynamic could be very different with the new rule. Nonetheless, the new dynamic would reinforce the trend we found (more incumbency advantage) thus making the simulation a valid exercise.

##Distribuicao dos assentos pelo modelo distritao.

##split per state
d.dist <- split(d, f = as.factor(d$sigla_Estado))

#Find how many were elected by state
d.dist.number <- c()
for (i in 1:length(d.dist)){
d.dist.number[i] <- nrow(d.dist[[i]][which(d.dist[[i]]$resultado_cod %in% c("3", "4")),])

##Rank each deputy in each state:
for (i in 1:length(d.dist)){
d.dist[[i]]$rank <- rank(-as.numeric(d.dist[[i]]$voto_nominal))

##Select for candidates where rank&lt;= amount of seats in that state
d.dist.elect <- list()
for (i in 1:length(d.dist)){
d.dist.elect[[i]] <- d.dist[[i]][which(d.dist[[i]]$rank <= d.dist.number[i]), ]

##Graph again amount of seats per party
d2 <-, d.dist.elect)

part2 <- data.frame(table(d2$partido_sig))
part2 <- arrange(part2, desc(Freq))
colnames(part2) <- c("party", "seats")

After these steps we have two datasets with the actual results of the current system (part1) and the simulated results of the ‘distritão’ system (part2). What is left to do is to join them and plot both results in a barplot using ggplot:

part1$regra <- "atual"
part2$regra <- "distritao"
part <- rbind(part1, part2)

p <- ggplot(data = part, aes(x = reorder(party, -seats), y = seats, fill = regra)) +
geom_bar(stat = "identity", position = position_dodge())+
geom_text(aes(label = seats), vjust=1.6, color="black",
position = position_dodge(0.9), size= 2)+
theme(axis.text.x = element_text(angle = 90, hjust = 1))+
labs(x = "party")


The result is the barplot below.

We used a similar code to run the simulation across all the 26 states in Brasil. The results for Rio de Janeiro are striking in terms of increasing incumbency advantage: largest party in the local legislation would increase its seats by 60%:


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s