Present value of external debt (% of GNI)

Source: worldbank.org, 03.09.2025

Year: 2023

Flag Country Value Value change, % Rank
Afghanistan Afghanistan 15.7 87
Angola Angola 59 5
Albania Albania 23.1 63
Argentina Argentina 11.8 98
Armenia Armenia 25.6 53
Azerbaijan Azerbaijan 17.9 82
Burundi Burundi 30.4 40
Benin Benin 32.4 37
Burkina Faso Burkina Faso 18.3 81
Bangladesh Bangladesh 12.8 95
Bosnia & Herzegovina Bosnia & Herzegovina 19.6 75
Belarus Belarus 26 52
Belize Belize 41.8 21
Bolivia Bolivia 25.5 55
Brazil Brazil 9.42 103
Botswana Botswana 9.06 105
Central African Republic Central African Republic 26.8 50
China China 2.77 112
Côte d’Ivoire Côte d’Ivoire 35.1 32
Cameroon Cameroon 23 64
Congo - Kinshasa Congo - Kinshasa 12.3 97
Congo - Brazzaville Congo - Brazzaville 43.7 18
Colombia Colombia 30 42
Comoros Comoros 19.7 74
Cape Verde Cape Verde 55.3 6
Costa Rica Costa Rica 19.4 77
Djibouti Djibouti 63.2 4
Dominica Dominica 45.9 15
Dominican Republic Dominican Republic 30.2 41
Algeria Algeria 1.95 113
Ecuador Ecuador 34.1 34
Egypt Egypt 31 39
Ethiopia Ethiopia 15.6 89
Fiji Fiji 27.2 48
Gabon Gabon 35 33
Georgia Georgia 32 38
Ghana Ghana 38.8 28
Guinea Guinea 18.6 79
Gambia Gambia 38.2 29
Guinea-Bissau Guinea-Bissau 43.8 17
Grenada Grenada 40.6 24
Guatemala Guatemala 11.6 99
Guyana Guyana 17.3 85
Honduras Honduras 24.4 57
Haiti Haiti 9.39 104
Indonesia Indonesia 16.9 86
India India 6.05 111
Iran Iran 1.67 114
Iraq Iraq 6.19 109
Jamaica Jamaica 50.4 9
Jordan Jordan 41.7 22
Kazakhstan Kazakhstan 10.9 101
Kenya Kenya 29.6 44
Kyrgyzstan Kyrgyzstan 26.2 51
Cambodia Cambodia 19.4 76
Laos Laos 65.5 2
Liberia Liberia 33.7 35
St. Lucia St. Lucia 40.7 23
Sri Lanka Sri Lanka 51.7 8
Lesotho Lesotho 36 31
Morocco Morocco 29.7 43
Moldova Moldova 15.7 88
Madagascar Madagascar 23 65
Maldives Maldives 53.5 7
Mexico Mexico 17.6 84
North Macedonia North Macedonia 37.7 30
Mali Mali 20.7 71
Myanmar (Burma) Myanmar (Burma) 13.4 93
Montenegro Montenegro 47.9 12
Mongolia Mongolia 46.3 14
Mozambique Mozambique 43.3 19
Mauritania Mauritania 28.8 46
Mauritius Mauritius 24.2 59
Malawi Malawi 18.4 80
Niger Niger 23.4 61
Nigeria Nigeria 12.8 96
Nicaragua Nicaragua 39.9 26
Nepal Nepal 13.8 91
Pakistan Pakistan 26.8 49
Peru Peru 15 90
Philippines Philippines 13 94
Papua New Guinea Papua New Guinea 24.3 58
Paraguay Paraguay 33.1 36
Rwanda Rwanda 40 25
Sudan Sudan 20 72
Senegal Senegal 50.3 10
Solomon Islands Solomon Islands 11.1 100
Sierra Leone Sierra Leone 22.8 66
El Salvador El Salvador 39.7 27
Somalia Somalia 23.5 60
Serbia Serbia 28.2 47
São Tomé & Príncipe São Tomé & Príncipe 47.7 13
Suriname Suriname 84.4 1
Eswatini Eswatini 22.3 68
Chad Chad 17.6 83
Togo Togo 20.9 70
Thailand Thailand 7.36 107
Tajikistan Tajikistan 20 73
Turkmenistan Turkmenistan 6.15 110
Timor-Leste Timor-Leste 9.78 102
Tunisia Tunisia 44.9 16
Turkey Turkey 13.5 92
Tanzania Tanzania 22.6 67
Uganda Uganda 21.9 69
Ukraine Ukraine 49 11
Uzbekistan Uzbekistan 25.5 54
St. Vincent & Grenadines St. Vincent & Grenadines 43.2 20
Vietnam Vietnam 8.45 106
Vanuatu Vanuatu 23.4 62
Samoa Samoa 29.2 45
Kosovo Kosovo 7.35 108
South Africa South Africa 25 56
Zambia Zambia 63.2 3
Zimbabwe Zimbabwe 19.2 78

                    
# 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 = 'DT.DOD.PVLX.GN.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 <- 'DT.DOD.PVLX.GN.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))