%
filter(euro_area) %>%
group_by(year) %>%
summarise(euro_area_mt = sum(total_mt), .groups = 'drop'),
by = 'year') %>%
mutate(EU27 = 100 * eu27_mt / world_mt,
`Euro area` = 100 * euro_area_mt / world_mt)
eu27_peak_year %
summarise(total_mt = sum(total_mt), population = sum(population),
n_countries = n_distinct(iso3), .groups = 'drop') %>%
left_join(world, by = 'year') %>%
left_join(world_population, by = 'year') %>%
mutate(per_capita_t = total_mt / population * 1e6,
emission_share = 100 * total_mt / world_mt,
population_share = 100 * population / world_population,
income_group = factor(income_group, levels = names(income_colours)))
income_value %
pivot_longer(c(emission_share, population_share), names_to = 'measure', values_to = 'share') %>%
mutate(measure = factor(measure, levels = c('emission_share', 'population_share'),
labels = c('of emissions', 'of population')))
p2b %
mutate(share = 100 * total_mt / world_2024) %>%
arrange(desc(total_mt)) %>%
slice_head(n = 20) %>%
mutate(country = factor(country, levels = rev(country)))
top_value %
arrange(desc(mt)) %>%
pull(sector)
sector_colours %
ungroup()
# Country names that take the definite article in running prose.
article %
left_join(countries %>% filter(year == 2024) %>% select(iso3, total_mt, population),
by = 'iso3') %>%
# Jointly reported territories take the HDI of the member whose code they carry
mutate(hdi_iso3 = ifelse(iso3 == 'SCG', 'SRB', iso3)) %>%
left_join(hdi %>% select(hdi_iso3 = iso3, hdi_2023, hdicode), by = 'hdi_iso3')
n_no_hdi %
# The full plotly bundle is about 3.4 MB, most of it chart types this figure
# does not use. partial_bundle() substitutes the smallest build that still
# covers the traces present. It fetches that build from the plotly CDN, so it
# falls back to the full bundle when the render has no network access.
lighter_bundle()
# knitr would otherwise fix the widget at fig.width x dpi, 768 px, which is
# wider than the 720 px text column and runs off the side of a phone screen.
# At 100% the widget follows its column and plotly redraws to that width.
fig5$width %
filter(iso_a3 != 'ATA') %>%
select(iso_a3, name_long) %>%
mutate(edgar_iso3 = coalesce(combined$iso3[match(iso_a3, combined$member_iso3)], iso_a3),
jointly = iso_a3 %in% combined$member_iso3) %>%
left_join(hdi_data %>% select(iso3, country, hdi_2023, per_capita_t, expected_t, residual, ratio),
by = c('edgar_iso3' = 'iso3'))
residual_limit % unname() %>% lapply(HTML)
# A fixed zoom shows a 512 px wide world, which a phone crops on both sides, so
# the map instead fits the inhabited latitudes to its container at a fractional
# zoom. On a narrow screen the fitted world is only about 240 px tall, so the
# container is shorter there and the world is fitted above the legend, which
# would otherwise cover South America.
leaflet(world_sf, width = '100%', height = 520, elementId = 'residual-map',
options = leafletOptions(minZoom = 0, maxZoom = 6, zoomSnap = 0.1, zoomDelta = 0.5,
worldCopyJump = TRUE)) %>%
addPolygons(fillColor = ~ residual_palette(residual), fillOpacity = 0.9,
color = 'white', weight = 0.6, smoothFactor = 0.3,
label = map_labels,
highlightOptions = highlightOptions(weight = 2, color = '#333333', bringToFront = TRUE)) %>%
# One legend box, with the no-data swatch under the scale, covers less of the map
addLegend(pal = residual_palette, values = c(-residual_limit, residual_limit, NA),
na.label = 'no data', title = 'Residual (log10)', position = 'bottomleft',
opacity = 0.9) %>%
fitBounds(lng1 = -170, lat1 = -56, lng2 = 180, lat2 = 84) %>%
htmlwidgets::onRender(
'function(el, x) {
if (window.matchMedia("(max-width: 600px)").matches) {
this.fitBounds([[-56, -170], [84, 180]], {paddingBottomRight: [0, 150], animate: false});
}
}') %>%
# leaflet floats the colour scale and its labels without clearing the float,
# so the no-data row would otherwise sit beside the scale instead of under it.
# The site's dark theme gives every link near-white text, which would leave the
# white zoom buttons and the attribution blank, so the map's links stay dark.
htmlwidgets::prependContent(tags$style(HTML(
'.leaflet-container { background: #f4f6f8; }
#residual-map .info.legend > div:last-child { clear: both; padding-top: 4px; }
#residual-map .leaflet-control a { color: #333 !important; -webkit-text-fill-color: #333 !important;
text-decoration: none !important; }
@media (max-width: 600px) { #residual-map { height: 410px !important; } }')))
Figure 6: The Residual of Each Country From That Model, Mapped. Source: EDGAR 2025 (Crippa et al., 2025), the Human Development Report 2025 (United Nations Development Programme, 2025) and Natural Earth boundaries via rnaturalearth. Units: residual of log10 per-capita emissions (2015 to 2024 mean) from the linear model on HDI 2023. The ratio of actual to expected emissions is 10residual. Boundaries carry no political meaning.
The largest positive residual belongs to Palau, at 11.6 times its expected level, and the largest negative one to Saint Vincent and the Grenadines, at 0.27 times. Tables 1 and 2 list the ten countries at each end. Oil and gas exporters fill most of the positive end, together with small states whose per-capita figure is set by one power plant or one fleet, such as Palau, with 23 thousand inhabitants. Two pastoral economies also appear there: in Mongolia, fuel extraction and livestock account for 73% of emissions, and in Chad, agriculture accounts for 90%. Methane from herds enters the total in full, and the model expects little of it at a low HDI, so a country whose emissions are mostly livestock lands above the line. Neither route makes these countries large emitters. Chad emits 101.2 Mt a year and Palau 1.5 Mt, against 51,847 Mt for the world, so the ratio ranks departures from the model and not contributions to the problem. The total column is in the tables to keep that in view, and it is worth reading before the ratio. The negative end mixes small island states with countries of South Asia and Sub-Saharan Africa whose emissions are low for their HDI. At the top of the HDI range, it also holds Switzerland, whose electricity comes largely from hydropower and nuclear plants and which EDGAR reports together with Liechtenstein. Because EDGAR reports Sudan and South Sudan as one territory, their combined per-capita figure is compared with the HDI of Sudan and mapped onto both countries.
# One table for each end of the residual, rather than one table of twenty rows
# split only by a word in its caption. The two ends are opposite findings, and
# running them together invited the reader to scan the whole list as a ranking.
residual_columns % transmute(Country = country, Continent = continent,
`HDI 2023` = fmt(hdi_2023, 3), `Total 2024 (Mt)` = fmt(total_mt, 1),
`Per capita (t)` = fmt(per_capita_t, 2),
`Expected (t)` = fmt(expected_t, 2), Ratio = fmt(ratio, 2))
}
hdi_data %>%
slice_max(residual, n = 10) %>%
residual_columns() %>%
kable(align = 'llrrrrr',
caption = paste('The Ten Countries Emitting Most Above the Level Expected at Their HDI.',
'Total is the 2024 national figure in Mt CO2eq, per capita the 2015 to',
'2024 mean in t CO2eq per person, expected the value fitted from the HDI',
'and ratio the actual over the expected. The ratio measures distance from',
'the model, not size: at a low HDI the model expects very little, so a',
'small total can produce a large ratio.'))
Table 1: The Ten Countries Emitting Most Above the Level Expected at Their HDI. Total is the 2024 national figure in Mt CO2eq, per capita the 2015 to 2024 mean in t CO2eq per person, expected the value fitted from the HDI and ratio the actual over the expected. The ratio measures distance from the model, not size: at a low HDI the model expects very little, so a small total can produce a large ratio.
Country
Continent
HDI 2023
Total 2024 (Mt)
Per capita (t)
Expected (t)
Ratio
Palau
Oceania
0.786
1.5
60.73
5.23
11.61
Qatar
Asia
0.886
162.7
52.69
8.53
6.18
Chad
Africa
0.416
101.2
5.00
0.86
5.84
Mongolia
Asia
0.747
104.4
23.21
4.32
5.37
Kuwait
Asia
0.852
173.3
35.97
7.22
4.98
Trinidad and Tobago
America
0.807
33.6
27.38
5.80
4.72
Bahrain
Asia
0.899
64.4
38.15
9.09
4.20
Turkmenistan
Asia
0.764
114.8
19.02
4.70
4.05
Brunei
Asia
0.837
11.9
25.28
6.71
3.77
Libya
Africa
0.721
98.2
12.77
3.81
3.36
hdi_data %>%
slice_min(residual, n = 10) %>%
arrange(desc(residual)) %>%
residual_columns() %>%
kable(align = 'llrrrrr',
caption = paste('The Ten Countries Emitting Most Below the Level Expected at Their HDI.',
'Columns as in Table 1.'))
Table 2: The Ten Countries Emitting Most Below the Level Expected at Their HDI. Columns as in Table 1.
Country
Continent
HDI 2023
Total 2024 (Mt)
Per capita (t)
Expected (t)
Ratio
Switzerland and Liechtenstein
Europe
0.970
43.0
5.40
12.86
0.42
Dominica
America
0.761
0.2
1.94
4.63
0.42
Comoros
Africa
0.603
0.9
0.89
2.14
0.42
Democratic Republic of the Congo
Africa
0.522
58.5
0.56
1.44
0.39
Bangladesh
Asia
0.685
220.8
1.21
3.19
0.38
Grenada
America
0.791
0.2
1.92
5.36
0.36
Sri Lanka
Asia
0.776
37.2
1.68
4.98
0.34
Kiribati
Oceania
0.644
0.1
0.87
2.61
0.33
Rwanda
Africa
0.578
8.3
0.59
1.89
0.31
Saint Vincent and the Grenadines
America
0.798
0.2
1.52
5.55
0.27
Whereas a few recurring causes account for Table 1, Table 2 has no single cause and spans HDI values from 0.52 to 0.97. Being far below the line is therefore not one phenomenon, and the countries there have little in common beyond the distance itself.
Discussion
Read together, the figures give a contextual account of emissions. Total emissions describe the size of each country’s annual contribution to the global total, and per-capita values describe the average emissions of its residents. Sector shares suggest where mitigation could begin, and the HDI residuals show departures from a broad relationship between development and emissions. These are complementary summaries, and their interpretation depends on the boundary choices documented above, especially the exclusion of land use, land-use change and forestry, and the treatment of international transport.
How the Figures Were Produced
The EDGAR sheets store years as columns, so each was reshaped to one row per territory and year before the totals and per-capita figures were joined by country code and year. Population-weighted means and population shares were computed from the derived population, and the world population is the sum over the territories that report a per-capita figure. Continents, income groups and the HDI were joined by ISO 3166 alpha-3 code. A few exceptions were handled by hand. Taiwan has no region in the ISO 3166 dataset. EDGAR has no row for Kosovo and files Curaçao under the code of the former Netherlands Antilles. The jointly reported territories keep the code under which EDGAR reports them. The model of Figure 5 is an ordinary least-squares regression of log10 per-capita emissions, averaged over 2015 to 2024, on the HDI for 2023, fitted to 183 countries. The document was rendered with R version 4.6.1 (2026-06-24 ucrt) and the packages dplyr 1.2.1, tidyr 1.3.2, ggplot2 4.0.3, patchwork 1.3.2, scales 1.4.0, ggrepel 0.9.8, ggtext 0.1.2, plotly 4.12.1, htmltools 0.5.9, leaflet 2.2.3, sf 1.1.2, rnaturalearth 1.2.0, rnaturalearthdata 1.0.0, RColorBrewer 1.1.3, knitr 1.51 and rmarkdown 2.31.
References
Crippa, M., Guizzardi, D., Pagani, F., Banja, M., Muntean, M., Schaaf, E., Quadrelli, R., Risquez Martin, A., Taghavi-Moharamli, P., Köykkä, J., Grassi, G., Rossi, S., Melo, J., Oom, D., Branco, A., Suárez-Moreno, M., Sedano, F., San-Miguel, J., Manca, G., … Pekar, F. (2025). GHG emissions of all world countries: 2025 report. Publications Office of the European Union. https://doi.org/10.2760/9816914
Duncalfe, L. (n.d.). ISO-3166-Countries-with-Regional-Codes [Data set]. GitHub. https://github.com/lukes/ISO-3166-Countries-with-Regional-Codes
United Nations Development Programme. (2025). Human development report 2025: A matter of choice: People and possibilities in the age of AI. United Nations. https://doi.org/10.18356/9789211542639
World Bank. (2025). World Bank country and lending groups: Current classification by income (Version 2025-07-02) [Data set]. https://datacatalogfiles.worldbank.org/ddh-published/0037712/DR0095333/CLASS_2025_07_02.xlsx
" />
[This article was first published on Pablo Bernabeu, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Related
To leave a comment for the author, please follow the link and comment on their blog: Pablo Bernabeu.