Modern slavery encompasses practices such as forced labour, forced marriage, debt bondage, human trafficking, and the exploitation of children.

# Load necessary libraries
pacman::p_load(readr, ggplot2, dplyr, tidyr, viridis, ggthemes, RColorBrewer, countrycode, gridExtra)

# Load the dataset
data <- read.csv("Age-of-Sexual-Consent.csv")

# Clean column names for easier use
colnames(data) <- c("country", "age_consent")

# Add a column to identify countries where marriage is required
data$requires_marriage <- ifelse(data$age_consent == "Must be married", TRUE, FALSE)

# Prepare the data for analysis
data$age_consent <- ifelse(data$age_consent %in% c("Must be married"), NA, data$age_consent)
data$age_consent <- as.numeric(as.character(data$age_consent))  # Convert age of consent to numeric

# Handle countries requiring marriage
marriage_countries <- data %>%
  filter(requires_marriage) %>%
  mutate(age_consent = NA)  # No bars for these countries

# Split the data into two halves: higher and lower ages of consent
data_high <- data %>%
  filter(!is.na(age_consent)) %>%
  arrange(desc(age_consent)) %>%
  slice(1:floor(n() / 2))  # Top half by age of consent

data_low <- data %>%
  filter(!is.na(age_consent)) %>%
  arrange(desc(age_consent)) %>%
  slice((floor(n() / 2) + 1):n())  # Bottom half by age of consent

# Add marriage countries to the lower chart
data_low <- bind_rows(data_low, marriage_countries) %>%
  arrange(desc(is.na(age_consent)), desc(age_consent))

# Caption
Caption <- "Data Visualisation: Patrick Ford"

# Create the bar chart for the top half
bar_chart_high <- ggplot(data_high, aes(x = reorder(country, age_consent), y = age_consent, fill = age_consent)) +
  geom_bar(stat = "identity") +
  coord_flip() +
  scale_fill_viridis_c(option = "viridis", name = "Age of Consent") +
  labs(title = "Higher Ages of Sexual Consent by Country 2025",
       subtitle = "Source: AgeOfConsent.net 2025",
       caption = Caption,
       x = "Country", y = "Age of Consent") +
  theme_minimal() +
  theme(axis.text.y = element_text(size = 8))

# Create the bar chart for the bottom half
bar_chart_low <- ggplot(data_low, aes(x = reorder(country, age_consent), y = age_consent, fill = age_consent)) +
  geom_bar(stat = "identity", na.rm = TRUE) +
  coord_flip() +
  scale_fill_viridis_c(option = "viridis", name = "Age of Consent") +
  labs(title = "Lower Ages of Sexual Consent by Country 2025",
       subtitle = "Source: AgeOfConsent.net 2025\n(Includes Countries Requiring Marriage (without bars); Effectively no Age of Consent)",
       caption = Caption,
       x = "Country", y = "Age of Consent") +
  theme_minimal() +
  theme(axis.text.y = element_text(size = 8))

# Arrange the charts side by side
grid.arrange(bar_chart_high, bar_chart_low, ncol = 2)

# Load the dataset
data <- read.csv("Percentage-of-Females-Married-by-15-years-old-2015-2023.csv")

# Clean column names for easier use
colnames(data) <- c("country", "percentage")  

# Convert `percentage` to numeric and handle missing values (`-`)
data <- data %>%
  mutate(
    percentage = as.numeric(percentage)  # Convert to numeric
  ) %>%
  filter(!is.na(percentage) & percentage > 0)  # Exclude invalid or zero values
## Warning: There was 1 warning in `mutate()`.
## ℹ In argument: `percentage = as.numeric(percentage)`.
## Caused by warning:
## ! NAs introduced by coercion
# Total number of rows after filtering
n_rows <- nrow(data)

# Split data into two halves for visualisation
data_high <- data %>%
  arrange(desc(percentage)) %>%
  slice(1:ceiling(n_rows / 2))  # Top half by percentage

data_low <- data %>%
  arrange(desc(percentage)) %>%
  slice((ceiling(n_rows / 2) + 1):n_rows)  # Bottom half by percentage

# Create bar chart for the top half (highest percentages at the top)
bar_chart_high <- ggplot(data_high, aes(x = reorder(country, percentage), y = percentage, fill = percentage)) +
  geom_bar(stat = "identity") +
  coord_flip() +
  scale_fill_viridis_c(option = "viridis", name = "Percentage") +
  labs(title = "Countries with Higher Percentages of Females Married by 15yrs Old",
       subtitle = "Source: UNICEF 2015-2023",
       caption = Caption,
       x = "Country", y = "Percentage") +
  theme_minimal() +
  theme(axis.text.y = element_text(size = 8))

# Create bar chart for the bottom half (highest percentages at the top)
bar_chart_low <- ggplot(data_low, aes(x = reorder(country, percentage), y = percentage, fill = percentage)) +
  geom_bar(stat = "identity") +
  coord_flip() +
  scale_fill_viridis_c(option = "viridis", name = "Percentage") +
  labs(title = "Countries with Lower Percentages of Females Married by 15yrs Old",
       subtitle = "Source: UNICEF 2015-2023",
       caption = Caption,
       x = "Country", y = "Percentage") +
  theme_minimal() +
  theme(axis.text.y = element_text(size = 8))

# Arrange the two charts side by side
grid.arrange(bar_chart_high, bar_chart_low, ncol = 2)

# Load the data
Global_Slavery_Index_2023 <- read_csv("Global_Slavery_Index_2023.csv")
## Rows: 180 Columns: 5
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (3): Country, Population, Region
## dbl (1): Estimated prevalence of modern slavery per 1,000 population
## num (1): Estimated number of people in modern slavery
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# Clean Population column (remove commas, convert to numeric, handle NAs)
Global_Slavery_Index_2023 <- Global_Slavery_Index_2023 %>%
  mutate(Population = as.numeric(gsub(",", "", Population)))
## Warning: There was 1 warning in `mutate()`.
## ℹ In argument: `Population = as.numeric(gsub(",", "", Population))`.
## Caused by warning:
## ! NAs introduced by coercion
# Remove rows with missing data in critical columns
Global_Slavery_Index_2023 <- Global_Slavery_Index_2023 %>%
  drop_na(`Estimated prevalence of modern slavery per 1,000 population`, 
          `Estimated number of people in modern slavery`)

### Prepare data for visualisation

# Top 20 and bottom 20 by prevalence
prevalence_sorted <- Global_Slavery_Index_2023 %>%
  arrange(desc(`Estimated prevalence of modern slavery per 1,000 population`))

top_20_prevalence <- prevalence_sorted %>% slice_head(n = 20)
bottom_20_prevalence <- prevalence_sorted %>% slice_tail(n = 20)

# Top 20 and bottom 20 by estimated number of people
number_sorted <- Global_Slavery_Index_2023 %>%
  arrange(desc(`Estimated number of people in modern slavery`))

top_20_number <- number_sorted %>% slice_head(n = 20)
bottom_20_number <- number_sorted %>% slice_tail(n = 20)

# Create a fixed colour palette for regions
region_colors <- RColorBrewer::brewer.pal(n = length(unique(Global_Slavery_Index_2023$Region)), "Dark2")
names(region_colors) <- unique(Global_Slavery_Index_2023$Region)

# Data label colour
Data_label <- "#ffffff"

# Subtitle
Subtitle <- "Source: Walk Free 2023, Global Slavery Index 2023"

# Create Plots

# Top 20 by prevalence
p1 <- ggplot(top_20_prevalence, aes(x = reorder(Country, `Estimated prevalence of modern slavery per 1,000 population`), 
                                    y = `Estimated prevalence of modern slavery per 1,000 population`, fill = Region)) +
  geom_bar(stat = "identity") +
  geom_text(aes(label = scales::comma(`Estimated prevalence of modern slavery per 1,000 population`)), 
            hjust = 1, color = Data_label, fontface = "bold", size = 3.5) +
  coord_flip() +
  scale_fill_manual(values = region_colors) +
  scale_y_continuous(labels = scales::comma) +
  labs(title = "Top 20 Countries by Estimated Prevalence of Modern Slavery",
       subtitle = Subtitle,
       caption = Caption,
       x = "Country", y = "Estimated Prevalence per 1,000 Population") +
  theme_minimal() +
  theme(legend.position = "bottom")

# Bottom 20 by prevalence
p2 <- ggplot(bottom_20_prevalence, aes(x = reorder(Country, `Estimated prevalence of modern slavery per 1,000 population`), 
                                       y = `Estimated prevalence of modern slavery per 1,000 population`, fill = Region)) +
  geom_bar(stat = "identity") +
  geom_text(aes(label = scales::comma(`Estimated prevalence of modern slavery per 1,000 population`)), 
            hjust = 1, color = Data_label, fontface = "bold", size = 3.5) +
  coord_flip() +
  scale_fill_manual(values = region_colors) +
  scale_y_continuous(labels = scales::comma) +
  labs(title = "Bottom 20 Countries by Estimated Prevalence of Modern Slavery",
       subtitle = Subtitle,
       caption = Caption,
       x = "Country", y = "Estimated Prevalence per 1,000 Population") +
  theme_minimal() +
  theme(legend.position = "bottom")

# Top 20 by estimated number of people
p3 <- ggplot(top_20_number, aes(x = reorder(Country, `Estimated number of people in modern slavery`), 
                                y = `Estimated number of people in modern slavery`, fill = Region)) +
  geom_bar(stat = "identity") +
  geom_text(aes(label = ifelse(`Estimated number of people in modern slavery` > 1e6, 
                               paste0(round(`Estimated number of people in modern slavery` / 1e6, 1), "M"), 
                               scales::comma(`Estimated number of people in modern slavery`))), 
            hjust = 1, color = Data_label, fontface = "bold", size = 3.5) +
  coord_flip() +
  scale_fill_manual(values = region_colors) +
  scale_y_continuous(labels = scales::comma) +
  labs(title = "Top 20 Countries by Estimated Number of People in Modern Slavery",
       subtitle = Subtitle,
       caption = Caption,
       x = "Country", y = "Estimated Number of People") +
  theme_minimal() +
  theme(legend.position = "bottom")

# Bottom 20 by estimated number of people
p4 <- ggplot(bottom_20_number, aes(x = reorder(Country, `Estimated number of people in modern slavery`), 
                                   y = `Estimated number of people in modern slavery`, fill = Region)) +
  geom_bar(stat = "identity") +
  geom_text(aes(label = scales::comma(`Estimated number of people in modern slavery`)), 
            hjust = 1, color = Data_label, fontface = "bold", size = 3.5) +
  coord_flip() +
  scale_fill_manual(values = region_colors) +
  scale_y_continuous(labels = scales::comma) +
  labs(title = "Bottom 20 Countries by Estimated Number of People in Modern Slavery",
       subtitle = Subtitle,
       caption = Caption,
       x = "Country", y = "Estimated Number of People") +
  theme_minimal() +
  theme(legend.position = "bottom")

# Arrange Plots Side by Side
grid.arrange(p1, p2, nrow = 2)

grid.arrange(p3, p4, nrow = 2)

grid.arrange(p3, p4, nrow = 2)