Code
library(pacman)
:: p_load(unvotes, lubridate, tidyverse, ggtext, knitr,
pacman dplyr, scales, tidyr, showtext, kableExtra, DT)
June 12, 2025
The package unvotes
allows us to access voting data from the UN. Today, we will analyse Brazil’s “Yes”, “No” and “Abstain” votes from 1995 to 2023 – a period that saw the country under 5 different presidents representing 5 distinct political parties and covers a significant portion of the country post-dictatorship democratic history. From FHC’s social and economical liberalism, to the rise of Lula’s and the Worker’s Party (PT) to power and the impeachment of his successor, Dilma Rousseff; the short, market-oriented presidency of Michel Temer and finally Bolsonaro’s far-right administration.
Note: the current administration under Lula (which took office in January 2023) is not featured in the package.
# Load the UN votes data
data("un_votes")
data("un_roll_calls")
data("un_roll_call_issues")
# Define Brazilian presidential administrations
brazil_administrations <- data.frame(
president = c("FHC I", "FHC II", "Lula I", "Lula II",
"Dilma I", "Dilma II", "Temer", "Bolsonaro", "Lula III"),
start_date = as.Date(c("1995-01-01", "1999-01-01", "2003-01-01", "2007-01-01",
"2011-01-01", "2015-01-01", "2016-08-31", "2019-01-01", "2023-01-01")),
end_date = as.Date(c("1998-12-31", "2002-12-31", "2006-12-31", "2010-12-31",
"2014-12-31", "2016-08-30", "2018-12-31", "2022-12-31", "2024-12-31")),
party = c("PSDB", "PSDB", "PT", "PT", "PT", "PT", "PMDB", "PSL/PL", "PT")
)
# Create Brazil-specific dataset with administrations
brazil_votes <- un_votes %>%
filter(country == "Brazil") %>%
left_join(un_roll_calls, by = "rcid") %>%
left_join(un_roll_call_issues, by = "rcid") %>%
mutate(year = year(date)) %>%
# Assign votes to administrations
rowwise() %>%
mutate(
administration = case_when(
date >= as.Date("1995-01-01") & date <= as.Date("1998-12-31") ~ "FHC I",
date >= as.Date("1999-01-01") & date <= as.Date("2002-12-31") ~ "FHC II",
date >= as.Date("2003-01-01") & date <= as.Date("2006-12-31") ~ "Lula I",
date >= as.Date("2007-01-01") & date <= as.Date("2010-12-31") ~ "Lula II",
date >= as.Date("2011-01-01") & date <= as.Date("2014-12-31") ~ "Dilma I",
date >= as.Date("2015-01-01") & date <= as.Date("2016-08-30") ~ "Dilma II",
date >= as.Date("2016-08-31") & date <= as.Date("2018-12-31") ~ "Temer",
date >= as.Date("2019-01-01") & date <= as.Date("2022-12-31") ~ "Bolsonaro",
date >= as.Date("2023-01-01") ~ "Lula III", #not featured on unvotes
TRUE ~ "Pre-1995"
)
) %>%
ungroup() %>%
filter(administration != "Pre-1995") %>%
mutate(
party = case_when(
administration %in% c("FHC I", "FHC II") ~ "PSDB",
administration %in% c("Lula I", "Lula II", "Dilma I", "Dilma II", "Lula III") ~ "PT",
administration == "Temer" ~ "PMDB",
administration == "Bolsonaro" ~ "PSL/PL"
)
)
Now that we have our data frame ready, we can look into more specific details. Let’s start with vote distribution by administration.
# Overall vote distribution by administration
vote_summary <- brazil_votes %>%
filter(!is.na(administration)) %>%
count(administration, vote, party) %>%
group_by(administration) %>%
mutate(
total_votes = sum(n),
percentage = n / total_votes * 100
) %>%
ungroup()
vote_summary %>%
select(administration, party, vote, n, percentage) %>%
arrange(administration, vote)
# A tibble: 21 × 5
administration party vote n percentage
<chr> <chr> <fct> <int> <dbl>
1 Bolsonaro PSL/PL yes 101 75.9
2 Bolsonaro PSL/PL abstain 24 18.0
3 Bolsonaro PSL/PL no 8 6.02
4 Dilma I PT yes 430 93.7
5 Dilma I PT abstain 26 5.66
6 Dilma I PT no 3 0.654
7 Dilma II PT yes 103 97.2
8 Dilma II PT abstain 3 2.83
9 FHC I PSDB yes 404 93.3
10 FHC I PSDB abstain 29 6.70
# ℹ 11 more rows
Now, we can visualize it:
#```{r plot-name, fig.width=12, fig.height=8, dpi=300, warning=FALSE, message=FALSE}
font_add_google("Nunito", "nunito", regular.wt = 400, bold.wt = 700)
showtext_auto()
showtext_opts(dpi = 300)
# Create ordered factor for proper chronological display
brazil_votes$administration_ordered <- factor(
brazil_votes$administration,
levels = c("FHC I", "FHC II", "Lula I", "Lula II",
"Dilma I", "Dilma II", "Temer", "Bolsonaro"))
vote_summary %>%
mutate(
administration_ordered = factor(administration,
levels = c("FHC I", "FHC II", "Lula I", "Lula II","Dilma I", "Dilma II", "Temer", "Bolsonaro"))
) %>%
ggplot(aes(x = administration_ordered, y = percentage, fill = vote)) +
geom_col(position = "stack", alpha = 0.8) +
scale_fill_manual(
values = c("abstain" = "#FFD700", "no" = "red", "yes" = "#2E8B57"), # Alphabetical order
labels = c("abstain" = "Abstain", "no" = "No", "yes" = "Yes")
) +
labs(
title = "Brazil's UN Voting Patterns by Presidential Administration",
subtitle = "Percentage distribution of Yes, No, and Abstain votes (1995-2023)",
x = "Presidential Administration",
y = "Percentage of Votes (%)",
fill = "Vote Type",
caption = "Data: {unvotes}"
) +
theme_minimal() +
theme(
plot.title = element_text(family = "nunito", size = 12),
plot.subtitle = element_text(family = "nunito", size = 8, margin = margin(b = .25, unit = "cm")),
plot.caption = element_text(family = "nunito", size = 8, margin = margin(t = .5, unit = "cm")),
panel.grid = element_blank(),
plot.background = element_rect(fill = "#fefefe", color = NA),
plot.margin = margin(c(.5,.5,.5,.5), unit = "cm"),
axis.text.x = element_text(angle = 45, hjust = 1 )
)
Now, we will take a look into how Brazil has voted in the main issues brought up at the General Assembly over the years.
Colonialism Arms control and disarmament
302 538
Economic development Human rights
228 535
Palestinian conflict Nuclear weapons and nuclear material
458 417
Excluding the NA values, there are six issues featured in our dataset: Economic development, Palestinian conflict, Arms control and disarmament, Human rights, Colonialism and Nuclear weapons and material.
# Examine voting patterns by issue type
issue_summary <- brazil_votes %>%
filter(!is.na(issue), !is.na(vote)) %>%
count(administration, issue, vote, party) %>%
group_by(administration, issue) %>%
mutate(
total_issue_votes = sum(n),
percentage = n / total_issue_votes * 100
) %>%
ungroup()
create_voting_summary <- function(issue_summary) {
# 1. Wide format table showing percentages by administration and issue
percentage_table <- issue_summary %>%
select(administration, issue, vote, percentage) %>%
pivot_wider(names_from = vote,
values_from = percentage,
values_fill = 0) %>%
arrange(match(administration, c("FHC I", "FHC II", "Lula I", "Lula II",
"Dilma I", "Dilma II", "Temer", "Bolsonaro")))
return(percentage_table)
}
voting_summary <- create_voting_summary(issue_summary)
formatted_table <- voting_summary %>%
kable(digits = 1,
caption = "Brazilian UN Assembly Voting Patterns (% by Administration and Issue)",
col.names = c("Administration", "Issue", "Abstain", "No", "Yes")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE,
font_size = 12) %>%
column_spec(1, bold = TRUE) %>%
column_spec(2, width = "4cm") %>%
collapse_rows(columns = 1, valign = "top")
formatted_table
Administration | Issue | Abstain | No | Yes |
---|---|---|---|---|
FHC I | Colonialism | 100.0 | 0.0 | 0.0 |
Arms control and disarmament | 88.1 | 11.9 | 0.0 | |
Economic development | 88.9 | 11.1 | 0.0 | |
Human rights | 95.6 | 4.4 | 0.0 | |
Palestinian conflict | 91.8 | 8.2 | 0.0 | |
Nuclear weapons and nuclear material | 92.5 | 7.5 | 0.0 | |
FHC II | Colonialism | 100.0 | 0.0 | 0.0 |
Arms control and disarmament | 86.7 | 13.3 | 0.0 | |
Economic development | 95.0 | 5.0 | 0.0 | |
Human rights | 91.2 | 8.8 | 0.0 | |
Palestinian conflict | 95.6 | 4.4 | 0.0 | |
Nuclear weapons and nuclear material | 87.1 | 12.9 | 0.0 | |
Lula I | Colonialism | 97.8 | 2.2 | 0.0 |
Arms control and disarmament | 90.7 | 9.3 | 0.0 | |
Economic development | 100.0 | 0.0 | 0.0 | |
Human rights | 76.6 | 23.4 | 0.0 | |
Palestinian conflict | 100.0 | 0.0 | 0.0 | |
Nuclear weapons and nuclear material | 92.1 | 7.9 | 0.0 | |
Lula II | Colonialism | 98.1 | 1.9 | 0.0 |
Arms control and disarmament | 98.9 | 1.1 | 0.0 | |
Economic development | 97.7 | 2.3 | 0.0 | |
Human rights | 82.2 | 17.8 | 0.0 | |
Palestinian conflict | 100.0 | 0.0 | 0.0 | |
Nuclear weapons and nuclear material | 98.6 | 1.4 | 0.0 | |
Dilma I | Colonialism | 100.0 | 0.0 | 0.0 |
Arms control and disarmament | 94.3 | 5.7 | 0.0 | |
Economic development | 94.9 | 5.1 | 0.0 | |
Human rights | 92.0 | 8.0 | 0.0 | |
Palestinian conflict | 100.0 | 0.0 | 0.0 | |
Nuclear weapons and nuclear material | 93.9 | 6.1 | 0.0 | |
Dilma II | Colonialism | 100.0 | 0.0 | 0.0 |
Arms control and disarmament | 100.0 | 0.0 | 0.0 | |
Economic development | 100.0 | 0.0 | 0.0 | |
Human rights | 95.0 | 5.0 | 0.0 | |
Palestinian conflict | 100.0 | 0.0 | 0.0 | |
Nuclear weapons and nuclear material | 100.0 | 0.0 | 0.0 | |
Temer | Colonialism | 90.0 | 10.0 | 0.0 |
Arms control and disarmament | 93.8 | 6.2 | 0.0 | |
Economic development | 94.2 | 3.8 | 1.9 | |
Human rights | 83.1 | 15.5 | 1.4 | |
Palestinian conflict | 91.8 | 6.1 | 2.0 | |
Nuclear weapons and nuclear material | 90.9 | 9.1 | 0.0 | |
Bolsonaro | Colonialism | 87.5 | 12.5 | 0.0 |
Arms control and disarmament | 87.5 | 12.5 | 0.0 | |
Economic development | 87.5 | 12.5 | 0.0 | |
Human rights | 50.0 | 28.6 | 21.4 | |
Palestinian conflict | 35.7 | 35.7 | 28.6 | |
Nuclear weapons and nuclear material | 88.2 | 11.8 | 0.0 |