This report analyzes the World Bank’s Gross Domestic Product ranking table for 2012 — GDP in millions of current US dollars for 190 ranked economies, plus a further 23 economies for which the World Bank had no confirmed estimate, plus regional and income-group aggregates (World, High income, Sub-Saharan Africa, Euro area, and so on).
The source file is a real-world “messy” spreadsheet export rather
than tidy data: it opens with four header/title rows, mixes
country-level and aggregate rows in the same columns, marks missing
values with "..", formats numbers with thousands separators
as text ("16,244,600"), and closes with dozens of blank
padding rows and footnotes. The cleaning step below turns this into an
analyzable table before anything else happens.
# NOTE: the original World Bank export is ISO-8859-1 encoded (it contains
# characters like "Côte d'Ivoire" and "São Tomé"). If you re-download the
# source file yourself, either read it with locale(encoding = "ISO-8859-1")
# or convert it to UTF-8 first (e.g. iconv -f ISO-8859-1 -t UTF-8) to avoid
# encoding errors on Windows.
raw <- read_csv("GDP.csv", skip = 4, col_names = FALSE,
col_types = cols(.default = "c"))
gdp_all <- raw %>%
transmute(
Code = X1,
Rank = suppressWarnings(as.numeric(X2)),
Economy = str_trim(X4),
GDP_raw = str_trim(X5),
Footnote = X6
) %>%
filter(!is.na(Economy)) %>%
mutate(GDP_musd = suppressWarnings(as.numeric(str_replace_all(GDP_raw, ",", ""))))
# Three tiers hiding in the same columns:
countries <- gdp_all %>% filter(!is.na(Rank)) # 190 ranked economies
no_data_econ <- gdp_all %>% filter(is.na(Rank), GDP_raw == "..") # economies with no confirmed estimate
aggregates <- gdp_all %>% filter(is.na(Rank), GDP_raw != "..", !is.na(GDP_musd)) # World / income / region totals
world_gdp <- aggregates %>% filter(Economy == "World") %>% pull(GDP_musd)
tibble(
Metric = c("Ranked economies", "Economies with no confirmed GDP estimate",
"Regional / income-group aggregate rows", "World GDP (millions of current US$)",
"Largest economy", "Smallest ranked economy"),
Value = c(
nrow(countries),
nrow(no_data_econ),
nrow(aggregates),
comma(world_gdp),
paste0(countries$Economy[which.min(countries$Rank)], " (Rank 1)"),
paste0(countries$Economy[which.max(countries$Rank)], " (Rank ", max(countries$Rank), ")")
)
) %>%
kable(caption = "Dataset snapshot") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
| Metric | Value |
|---|---|
| Ranked economies | 190 |
| Economies with no confirmed GDP estimate | 23 |
| Regional / income-group aggregate rows | 14 |
| World GDP (millions of current US$) | 72,440,449 |
| Largest economy | United States (Rank 1) |
| Smallest ranked economy | Tuvalu (Rank 190) |
The 190 ranked economies account for essentially all measurable world output; the remaining 23 (e.g. North Korea, Libya, Somalia, Myanmar, several small territories) are excluded from ranking specifically because the World Bank had no confirmed estimate for them that year — not because their economies are zero.
top20 <- countries %>% arrange(Rank) %>% slice_head(n = 20)
ggplot(top20, aes(x = fct_reorder(Economy, GDP_musd), y = GDP_musd)) +
geom_col(fill = "#2c7fb8") +
geom_text(aes(label = comma(GDP_musd)), hjust = -0.1, size = 3) +
coord_flip(clip = "off") +
scale_y_continuous(labels = comma, expand = expansion(mult = c(0, 0.2))) +
labs(title = "Top 20 economies by GDP, 2012",
x = NULL, y = "GDP (millions of current US$)") +
theme_minimal(base_size = 12)
us_gdp <- countries %>% filter(Economy == "United States") %>% pull(GDP_musd)
china_gdp <- countries %>% filter(Economy == "China") %>% pull(GDP_musd)
japan_gdp <- countries %>% filter(Economy == "Japan") %>% pull(GDP_musd)
top3_share <- (us_gdp + china_gdp + japan_gdp) / world_gdp
top10_share <- top20 %>% filter(Rank <= 10) %>% summarise(s = sum(GDP_musd) / world_gdp) %>% pull(s)
A few things stand out immediately from the top of the table:
ggplot(countries, aes(x = GDP_musd)) +
geom_histogram(bins = 40, fill = "#2c7fb8") +
scale_x_log10(labels = comma) +
labs(title = "Distribution of GDP across all 190 ranked economies (log scale)",
x = "GDP, millions of current US$ (log scale)", y = "Number of economies") +
theme_minimal(base_size = 12)
countries %>%
summarise(
Mean = mean(GDP_musd), Median = median(GDP_musd),
`Std. Dev.` = sd(GDP_musd), Min = min(GDP_musd), Max = max(GDP_musd)
) %>%
mutate(across(everything(), comma)) %>%
kable(caption = "Summary statistics across all 190 ranked economies (millions of current US$)") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
| Mean | Median | Std. Dev. | Min | Max |
|---|---|---|---|---|
| 377,652 | 27,638 | 1,451,248 | 40 | 16,244,600 |
GDP across countries is heavily right-skewed — the mean ($381 billion) is roughly nine times the median ($41.5 billion), meaning a handful of very large economies pull the average far above what a “typical” country produces. This is why a log scale is necessary to see the shape of the distribution at all on a linear chart: on a raw linear axis, 185 of the 190 bars would be visually indistinguishable from zero next to the United States.
income_order <- c("Low income", "Lower middle income", "Upper middle income", "High income")
income_groups <- aggregates %>%
filter(Economy %in% income_order) %>%
mutate(Economy = factor(Economy, levels = income_order),
share = GDP_musd / (aggregates %>% filter(Economy == "Low & middle income") %>% pull(GDP_musd) +
aggregates %>% filter(Economy == "High income") %>% pull(GDP_musd)))
ggplot(income_groups, aes(x = Economy, y = GDP_musd, fill = Economy)) +
geom_col(show.legend = FALSE) +
geom_text(aes(label = comma(GDP_musd)), vjust = -0.4, size = 3.5) +
scale_fill_brewer(palette = "Blues") +
scale_y_continuous(labels = comma, expand = expansion(mult = c(0, 0.15))) +
labs(title = "World GDP by World Bank income classification, 2012",
x = NULL, y = "GDP (millions of current US$)") +
theme_minimal(base_size = 12)
High-income economies produced roughly 69% of the GDP represented across all classified income groups — more than double the combined output of low, lower-middle, and upper-middle income economies put together, despite those groups containing the large majority of the world’s countries and population. This single chart is a compact illustration of global income inequality at the country level.
region_order <- c("East Asia & Pacific", "Europe & Central Asia", "Latin America & Caribbean",
"Middle East & North Africa", "South Asia", "Sub-Saharan Africa")
regions <- aggregates %>%
filter(Economy %in% region_order) %>%
mutate(Economy = factor(Economy, levels = region_order))
ggplot(regions, aes(x = fct_reorder(Economy, GDP_musd), y = GDP_musd)) +
geom_col(fill = "#31a354") +
geom_text(aes(label = comma(GDP_musd)), hjust = -0.1, size = 3.5) +
coord_flip(clip = "off") +
scale_y_continuous(labels = comma, expand = expansion(mult = c(0, 0.2))) +
labs(title = "GDP by developing-world region, 2012\n(World Bank regional classification)",
x = NULL, y = "GDP (millions of current US$)") +
theme_minimal(base_size = 12)
Note that the World Bank’s regional breakdown here covers developing regions only — North America, and high-income Europe/East Asia, are folded into the “High income” group above rather than given their own regional bar. Within the developing-region view, East Asia & Pacific (dominated by China) produces more than the other five developing regions combined, while Sub-Saharan Africa — home to a large share of the world’s countries — accounts for the smallest regional total.
For reference, the Euro area (the 17–19 EU countries using the euro) alone produced $12.2 trillion, roughly 75% of U.S. GDP and well above any individual country other than the US, China, or Japan — a reminder that currency-union aggregates can rival individual major economies.
no_data_econ %>%
select(Economy) %>%
arrange(Economy) %>%
kable(caption = paste0("Economies excluded from ranking (", nrow(no_data_econ), " total) — no confirmed 2012 GDP estimate")) %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
scroll_box(height = "300px")
| Economy |
|---|
| American Samoa |
| Andorra |
| Cayman Islands |
| Channel Islands |
| Curaçao |
| Faeroe Islands |
| French Polynesia |
| Greenland |
| Guam |
| Isle of Man |
| Korea, Dem. Rep. |
| Libya |
| Liechtenstein |
| Myanmar |
| New Caledonia |
| Northern Mariana Islands |
| San Marino |
| Sint Maarten (Dutch part) |
| Somalia |
| St. Martin (French part) |
| Turks and Caicos Islands |
| Virgin Islands (U.S.) |
| West Bank and Gaza |
These 23 economies were excluded from the ranking entirely, not assigned a GDP of zero. Several patterns explain the gaps: conflict or fragile states (Somalia, Libya, West Bank and Gaza), isolated or heavily sanctioned economies (North Korea, Myanmar), and a long tail of small dependent territories (Greenland, Guam, the Cayman Islands, several Pacific and Caribbean island territories) whose national accounts are either not separately compiled or not reported to the World Bank on the same timetable as sovereign states.
A handful of ranked countries carry a footnote qualifying how their figure was derived (e.g. territorial exclusions or data-coverage caveats):
countries %>%
filter(!is.na(Footnote)) %>%
select(Economy, GDP_musd, Footnote) %>%
mutate(GDP_musd = comma(GDP_musd)) %>%
kable(col.names = c("Economy", "GDP (millions US$)", "Footnote"),
caption = "Ranked countries with a data-coverage footnote") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
| Economy | GDP (millions US$) | Footnote |
|---|---|---|
| Morocco | 95,982 | a |
| Sudan | 58,769 | b |
| Tanzania | 28,242 | c |
| Cyprus | 22,767 | d |
| Georgia | 15,747 | e |
| Moldova | 7,253 | f |
For example, Morocco’s figure includes the former Spanish Sahara, Sudan’s excludes South Sudan (which had just separated the year before), and Cyprus’s covers only the area controlled by the Republic of Cyprus government — details that matter for anyone using these figures in a longer time series that spans the relevant political changes.
countries %>%
arrange(Rank) %>%
select(Rank, Economy, `GDP (millions US$)` = GDP_musd) %>%
datatable(options = list(pageLength = 15, scrollX = TRUE), rownames = FALSE, filter = "top")
This is a single-year (2012), nominal (not inflation- or purchasing-power-adjusted) snapshot in current US dollars, so it is sensitive to that year’s exchange rates and says nothing about growth, trend, or standard of living. It also contains no population data, so it cannot support per-capita comparisons on its own — a country’s total GDP rank reflects population size as much as prosperity (e.g. India ranks 10th in total GDP despite a much lower GDP per person than many smaller economies further down the list). A companion population file would be needed to convert any of these figures to a per-capita basis.
Report generated in R Markdown. To publish: put
GDP.csv in the same folder as this file, open it in
RStudio, click Knit, then use the
Publish button (top right of the preview pane) to push
directly to RPubs.