R Markdown

knitr::opts_chunk$set(echo = TRUE, warning = FALSE, message = FALSE)

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.2.1     ✔ readr     2.2.0
## ✔ forcats   1.0.1     ✔ stringr   1.6.0
## ✔ ggplot2   4.0.3     ✔ tibble    3.3.1
## ✔ lubridate 1.9.5     ✔ tidyr     1.3.2
## ✔ purrr     1.2.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(dplyr)
library(ggplot2)
library(readr)

raw_data <- read_csv(("API_SE.SEC.ENRR_DS2_en_csv_v2_330266.csv"), skip = 4)
## New names:
## Rows: 265 Columns: 71
## ── Column specification
## ──────────────────────────────────────────────────────── Delimiter: "," chr
## (4): Country Name, Country Code, Indicator Name, Indicator Code dbl (56): 1970,
## 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, ... lgl (11): 1960,
## 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, ...71
## ℹ 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.
## • `` -> `...71`
clean_data <- raw_data %>%
  select(`Country Name`, `Country Code`, `2021`) %>%
  rename(
    country = `Country Name`,
    code = `Country Code`,
    enrollment_rate = `2021`
  ) %>%
  drop_na(enrollment_rate) %>%
  mutate(
    performance_tier = case_when(
      enrollment_rate < 50 ~ "Low (< 50%)",
      enrollment_rate >= 50 & enrollment_rate < 85 ~ "Moderate (50-84%)",
      enrollment_rate >= 85 ~ "High (85%+)"
    ),
    performance_tier = factor(
      performance_tier, 
      levels = c("Low (< 50%)", "Moderate (50-84%)", "High (85%+)")
    )
  )

head(clean_data)
## # A tibble: 6 × 4
##   country                     code  enrollment_rate performance_tier 
##   <chr>                       <chr>           <dbl> <fct>            
## 1 Aruba                       ABW             124.  High (85%+)      
## 2 Africa Eastern and Southern AFE              45.2 Low (< 50%)      
## 3 Africa Western and Central  AFW              45.6 Low (< 50%)      
## 4 Angola                      AGO              53.1 Moderate (50-84%)
## 5 Albania                     ALB              97.7 High (85%+)      
## 6 Andorra                     AND              98.0 High (85%+)

Key Insight 1: Distribution of Countries Across Enrollment Tiers

tier_counts <- clean_data %>%
  count(performance_tier, name = "total_count")

tier_counts
## # A tibble: 3 × 2
##   performance_tier  total_count
##   <fct>                   <int>
## 1 Low (< 50%)                26
## 2 Moderate (50-84%)          43
## 3 High (85%+)               124

Key Insight 2: Descriptive Metrics by Performance Tier

# Summarize statistics by tier
tier_summary <- clean_data %>%
  group_by(performance_tier) %>%
  summarize(
    avg_enrollment = round(mean(enrollment_rate), 2),
    median_enrollment = round(median(enrollment_rate), 2),
    min_enrollment = round(min(enrollment_rate), 2),
    max_enrollment = round(max(enrollment_rate), 2),
    country_count = n()
  )

tier_summary
## # A tibble: 3 × 6
##   performance_tier  avg_enrollment median_enrollment min_enrollment
##   <fct>                      <dbl>             <dbl>          <dbl>
## 1 Low (< 50%)                 42.5              45.2           23.2
## 2 Moderate (50-84%)           72.0              74.0           53.1
## 3 High (85%+)                103.              101.            85.5
## # ℹ 2 more variables: max_enrollment <dbl>, country_count <int>

Histogram of Distribution of Secondary School Enrollment Tiers (2021)

ggplot(tier_counts, aes(x = performance_tier, y = total_count, fill = performance_tier)) +
  geom_col(width = 0.6, show.legend = FALSE) +
  geom_text(aes(label = total_count), vjust = -0.5, fontface = "bold") +
  scale_fill_brewer(palette = "Set2") +
  labs(
    title = "Distribution of Secondary School Enrollment Tiers (2021)",
    subtitle = "Based on World Bank Indicator: Gross Secondary Enrollment (%)",
    x = "Enrollment Tier",
    y = "Number of Countries / Regions",
    caption = "Source: World Bank Open Data"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(face = "bold", size = 14),
    axis.text = element_text(size = 10)
  ) +
  ylim(0, max(tier_counts$total_count) + 15)