Pupil-teacher ratio, upper secondary

Source: worldbank.org, 03.09.2025

Year: 2018

Flag Country Value Value change, % Rank
Afghanistan Afghanistan 32.8 +0.535% 2
Albania Albania 13.4 -4.48% 32
Armenia Armenia 4.46 57
Azerbaijan Azerbaijan 9.18 47
Burundi Burundi 20 +23.5% 16
Burkina Faso Burkina Faso 23.1 -0.893% 13
Bangladesh Bangladesh 28.7 -8.07% 4
Bahrain Bahrain 9.25 -1.48% 46
Bahamas Bahamas 12.3 -8.65% 34
Bosnia & Herzegovina Bosnia & Herzegovina 9.86 -1.64% 41
Belarus Belarus 8.91 +3.47% 48
Belize Belize 15.1 +0.169% 25
Barbados Barbados 15.4 -1.22% 24
Brunei Brunei 7.78 -5.03% 53
Bhutan Bhutan 7.86 -0.537% 52
China China 14.5 -1.26% 29
Colombia Colombia 25 -0.418% 10
Comoros Comoros 6.88 +59.3% 55
Cape Verde Cape Verde 15 -1.02% 26
Costa Rica Costa Rica 12.3 -6.7% 35
Cuba Cuba 9.56 +3.37% 44
Cayman Islands Cayman Islands 10.3 +124% 39
Djibouti Djibouti 21.2 +28.1% 14
Ecuador Ecuador 18.7 -3.42% 18
Egypt Egypt 13.4 +1.41% 31
Eritrea Eritrea 27.6 -11.9% 5
Georgia Georgia 6.92 -4.34% 54
Ghana Ghana 23.4 +7.71% 12
Grenada Grenada 12.8 +8.7% 33
Guatemala Guatemala 8.15 -0.882% 50
Indonesia Indonesia 15 -3.51% 28
India India 33.1 +13.1% 1
Jordan Jordan 8.4 -0.172% 49
Laos Laos 20 +0.0054% 15
St. Lucia St. Lucia 11 -2.77% 37
Sri Lanka Sri Lanka 18.5 +3.45% 19
Macao SAR China Macao SAR China 9.26 -2.98% 45
Morocco Morocco 15.8 -2.79% 21
Moldova Moldova 10.1 -5.93% 40
Madagascar Madagascar 18.1 -1.26% 20
Myanmar (Burma) Myanmar (Burma) 23.9 +8.95% 11
Montenegro Montenegro 14.4 +3.03% 30
Mauritania Mauritania 15.4 -0.0926% 23
Oman Oman 9.69 -1.98% 43
Pakistan Pakistan 29 -0.000517% 3
North Korea North Korea 15.8 -2.15% 22
Palestinian Territories Palestinian Territories 15 -3.31% 27
Qatar Qatar 10.4 +8.4% 38
Rwanda Rwanda 25.2 +54.4% 9
Saudi Arabia Saudi Arabia 11.4 +1.92% 36
Senegal Senegal 19.3 -23.4% 17
El Salvador El Salvador 27.2 +3.22% 6
San Marino San Marino 5.34 56
Serbia Serbia 8.12 -1.19% 51
Thailand Thailand 27.1 -1.35% 7
Timor-Leste Timor-Leste 26 -2.85% 8
Tuvalu Tuvalu 9.82 +38.4% 42

The pupil-teacher ratio in upper secondary education serves as a critical indicator of educational quality and accessibility. It reflects the number of students per teacher in this specific education level, highlighting the capacity of educational institutions to provide personalized attention and instruction. A lower pupil-teacher ratio is generally associated with improved educational outcomes, as teachers can devote more time and resources to each student. In contrast, higher ratios may lead to overcrowded classrooms, which can hinder effective teaching and learning processes.

Understanding the significance of the pupil-teacher ratio sheds light on the nuances of educational planning and policy-making. With a median value of 22.65 in 2019, this ratio shows that, on average, there are approximately 23 students for every teacher at the upper secondary level. This figure is essential not only for evaluating current educational standards but also for making comparisons across different regions and countries. The top three areas reporting the highest pupil-teacher ratios—Nepal at 24.86, Djibouti at 22.65, and Ghana at 19.6—demonstrate varying educational challenges. For instance, Nepal’s higher ratio suggests that students in this region may experience a less personalized learning environment compared to those in countries with lower ratios.

In contrast, the bottom areas like Ghana, Djibouti, and Nepal also illustrate the complexities of educational systems in emerging economies where limited resources often dictate the capability of schools to hire additional teachers. The interplay here indicates that regions with lower economic status may find themselves grappling with educational disparities, resulting in increased pupil-teacher ratios. This creates a feedback loop where students’ engagement and performance suffer, which can further perpetuate socioeconomic constraints.

The historical context of pupil-teacher ratios provides an insight into global educational trends. Back in 1993, the world pupil-teacher ratio was much lower, at 15.17, but has shown a consistent increase over the years, peaking at 17.61 in 2015 and slightly declining to 17.16 in 2018. Analyzing this trend reveals a concerning trajectory in which global progress toward reducing pupil-teacher ratios in upper secondary education appears stagnated. Such stagnation might be linked to increasing enrollments in upper secondary education outpacing the growth in the number of qualified teachers. Thus, it becomes imperative to investigate various factors influencing these trends.

Several factors affect pupil-teacher ratios, including economic conditions, government policy, population growth, and educational funding. A stable economy often leads to increased governmental and private investment in education. Countries with robust economic support systems are more likely to maintain a favorable pupil-teacher ratio, as they can afford to hire more teachers to accommodate rising student enrollments. Furthermore, systemic issues such as curriculum changes or shifting educational priorities can also influence the pupil-teacher ratio. For example, initiatives aimed at increasing access to upper secondary education, particularly in developing nations, may inadvertently lead to higher ratios if not paired with adequate teacher training programs.

Strategies to improve the pupil-teacher ratio include increasing investment in teacher training and recruitment, developing incentive programs to attract educators to underserved areas, and implementing educational reforms that prioritize smaller class sizes. For instance, government strategies might focus on recruiting additional teachers as enrollment figures rise. Moreover, innovative solutions, such as employing technology in classroom settings for personalized learning experiences, may help mitigate the impacts of higher pupil-teacher ratios by maximizing teacher productivity and student engagement.

Nonetheless, several flaws exist in current approaches to managing pupil-teacher ratios effectively. One significant issue is the variability in educational quality associated with ratios themselves. A low pupil-teacher ratio does not guarantee high educational outcomes if teachers lack the necessary training or resources to deliver effective instructions. Moreover, simply increasing the number of teachers without addressing training and classroom conditions may lead to minimal improvements in educational efficacy. Therefore, while addressing pupil-teacher ratios is crucial, it alone cannot resolve the wider issues of educational inequality and quality that persist globally.

In conclusion, the pupil-teacher ratio in upper secondary education serves as a key indicator that unveils various underlying educational challenges. As evidenced by the data from 2019, the global median value of 22.65 and the contextual variations observed across different regions highlight the need for focused policies aimed at improving educational access and quality. By understanding the relationships involving this indicator—especially in relation to economic conditions and educational policies—stakeholders can devise more effective strategies aimed at ensuring that every student receives a quality education paired with adequate teacher support. Thus, a multi-faceted approach is essential for not only improving pupil-teacher ratios but also for enhancing overall educational outcomes for students around the world.

                    
# Install missing packages
import sys
import subprocess

def install(package):
subprocess.check_call([sys.executable, "-m", "pip", "install", package])

# Required packages
for package in ['wbdata', 'country_converter']:
try:
__import__(package)
except ImportError:
install(package)

# Import libraries
import wbdata
import country_converter as coco
from datetime import datetime

# Define World Bank indicator code
dataset_code = 'SE.SEC.ENRL.UP.TC.ZS'

# Download data from World Bank API
data = wbdata.get_dataframe({dataset_code: 'value'},
date=(datetime(1960, 1, 1), datetime.today()),
parse_dates=True,
keep_levels=True).reset_index()

# Extract year
data['year'] = data['date'].dt.year

# Convert country names to ISO codes using country_converter
cc = coco.CountryConverter()
data['iso2c'] = cc.convert(names=data['country'], to='ISO2', not_found=None)
data['iso3c'] = cc.convert(names=data['country'], to='ISO3', not_found=None)

# Filter out rows where ISO codes could not be matched — likely not real countries
data = data[data['iso2c'].notna() & data['iso3c'].notna()]

# Sort for calculation
data = data.sort_values(['iso3c', 'year'])

# Calculate YoY absolute and percent change
data['value_change'] = data.groupby('iso3c')['value'].diff()
data['value_change_percent'] = data.groupby('iso3c')['value'].pct_change() * 100

# Calculate ranks (higher GDP per capita = better rank)
data['rank'] = data.groupby('year')['value'].rank(ascending=False, method='dense')

# Calculate rank change from previous year
data['rank_change'] = data.groupby('iso3c')['rank'].diff()

# Select desired columns
final_df = data[['country', 'iso2c', 'iso3c', 'year', 'value',
'value_change', 'value_change_percent', 'rank', 'rank_change']].copy()

# Optional: Add labels as metadata (could be useful for export or UI)
column_labels = {
'country': 'Country name',
'iso2c': 'ISO 2-letter country code',
'iso3c': 'ISO 3-letter country code',
'year': 'Year',
'value': 'GDP per capita (current US$)',
'value_change': 'Year-over-Year change in value',
'value_change_percent': 'Year-over-Year percent change in value',
'rank': 'Country rank by GDP per capita (higher = richer)',
'rank_change': 'Change in rank from previous year'
}

# Display first few rows
print(final_df.head(10))

# Optional: Save to CSV
#final_df.to_csv("gdp_per_capita_cleaned.csv", index=False)
                    
                
                    
# Check and install required packages
required_packages <- c("WDI", "countrycode", "dplyr")

for (pkg in required_packages) {
  if (!requireNamespace(pkg, quietly = TRUE)) {
    install.packages(pkg)
  }
}

# Load the necessary libraries
library(WDI)
library(dplyr)
library(countrycode)

# Define the dataset code (World Bank indicator code)
dataset_code <- 'SE.SEC.ENRL.UP.TC.ZS'

# Download data using WDI package
dat <- WDI(indicator = dataset_code)

# Filter only countries using 'is_country' from countrycode
# This uses iso2c to identify whether the entry is a recognized country
dat <- dat %>%
  filter(countrycode(iso2c, origin = 'iso2c', destination = 'country.name', warn = FALSE) %in%
           countrycode::codelist$country.name.en)

# Ensure dataset is ordered by country and year
dat <- dat %>%
  arrange(iso3c, year)

# Rename the dataset_code column to "value" for easier manipulation
dat <- dat %>%
  rename(value = !!dataset_code)

# Calculate year-over-year (YoY) change and percentage change
dat <- dat %>%
  group_by(iso3c) %>%
  mutate(
    value_change = value - lag(value),                              # Absolute change from previous year
    value_change_percent = 100 * (value - lag(value)) / lag(value) # Percent change from previous year
  ) %>%
  ungroup()

# Calculate rank by year (higher value => higher rank)
dat <- dat %>%
  group_by(year) %>%
  mutate(rank = dense_rank(desc(value))) %>% # Rank countries by descending value
  ungroup()

# Calculate rank change (positive = moved up, negative = moved down)
dat <- dat %>%
  group_by(iso3c) %>%
  mutate(rank_change = rank - lag(rank)) %>% # Change in rank compared to previous year
  ungroup()

# Select and reorder final columns
final_data <- dat %>%
  select(
    country,
    iso2c,
    iso3c,
    year,
    value,
    value_change,
    value_change_percent,
    rank,
    rank_change
  )

# Add labels (variable descriptions)
attr(final_data$country, "label") <- "Country name"
attr(final_data$iso2c, "label") <- "ISO 2-letter country code"
attr(final_data$iso3c, "label") <- "ISO 3-letter country code"
attr(final_data$year, "label") <- "Year"
attr(final_data$value, "label") <- "GDP per capita (current US$)"
attr(final_data$value_change, "label") <- "Year-over-Year change in value"
attr(final_data$value_change_percent, "label") <- "Year-over-Year percent change in value"
attr(final_data$rank, "label") <- "Country rank by GDP per capita (higher = richer)"
attr(final_data$rank_change, "label") <- "Change in rank from previous year"

# Print the first few rows of the final dataset
print(head(final_data, 10))