The Data

This report uses the World Bank’s Life expectancy at birth, total (years) indicator (SP.DYN.LE00.IN) from the World Development Indicators. The download contains two files:

Reading In the Raw Data

The World Bank file has 4 lines of notes above the real header, so we skip them. check.names = FALSE keeps the year columns named 2000, 2022, etc.

life_raw <- read.csv("lifeexp.csv", skip = 4, check.names = FALSE)
meta     <- read.csv("metadata.csv", check.names = FALSE,
                     fileEncoding = "UTF-8-BOM")

dim(life_raw)
## [1] 265  71

Why the Data Needs Cleaning

The raw data has three problems:

  1. Wide format: there is one column per year, but we only need two years.
  2. Missing values: some countries have no data for some years.
  3. Aggregates mixed in: rows like “World” and “Sub-Saharan Africa” sit alongside real countries. In the metadata these rows have a blank region.
# Missing values in the two years we'll compare
sum(is.na(life_raw$`2000`))
## [1] 1
sum(is.na(life_raw$`2022`))
## [1] 1
# Aggregate rows (blank region in the metadata)
sum(meta$Region == "")
## [1] 47

Formatting the Data

life <- life_raw %>%
  select(country = `Country Name`, code = `Country Code`,
         le_2000 = `2000`, le_2022 = `2022`) %>%
  inner_join(meta %>% select(code = `Country Code`,
                             region = Region, income = IncomeGroup),
             by = "code") %>%
  filter(region != "", income != "") %>%          # drop aggregates/unclassified
  filter(!is.na(le_2000), !is.na(le_2022)) %>%    # drop missing values
  mutate(gain   = le_2022 - le_2000,
         income = factor(income, levels = c("Low income",
                                            "Lower middle income",
                                            "Upper middle income",
                                            "High income")))

nrow(life)
## [1] 217
head(life)
##                country code le_2000 le_2022                     region
## 1                Aruba  ABW  72.939  76.226  Latin America & Caribbean
## 2          Afghanistan  AFG  55.005  65.617 Middle East & North Africa
## 3               Angola  AGO  46.501  64.246         Sub-Saharan Africa
## 4              Albania  ALB  74.826  78.769      Europe & Central Asia
## 5              Andorra  AND  81.863  84.016      Europe & Central Asia
## 6 United Arab Emirates  ARE  76.347  80.487 Middle East & North Africa
##                income   gain
## 1         High income  3.287
## 2          Low income 10.612
## 3 Lower middle income 17.745
## 4 Upper middle income  3.943
## 5         High income  2.153
## 6         High income  4.140

How Many Countries Are in Each Group?

life %>% count(region, sort = TRUE)
##                       region  n
## 1      Europe & Central Asia 58
## 2         Sub-Saharan Africa 48
## 3  Latin America & Caribbean 42
## 4        East Asia & Pacific 37
## 5 Middle East & North Africa 23
## 6                 South Asia  6
## 7              North America  3
life %>% count(income)
##                income  n
## 1          Low income 25
## 2 Lower middle income 47
## 3 Upper middle income 59
## 4         High income 86

Insight 1: Gains by Region

region_summary <- life %>%
  group_by(region) %>%
  summarize(countries = n(),
            avg_2000  = round(mean(le_2000), 1),
            avg_2022  = round(mean(le_2022), 1),
            avg_gain  = round(mean(gain), 1)) %>%
  arrange(desc(avg_gain))

knitr::kable(region_summary,
             col.names = c("Region", "Countries", "Avg 2000",
                           "Avg 2022", "Avg Gain (yrs)"))
Region Countries Avg 2000 Avg 2022 Avg Gain (yrs)
Sub-Saharan Africa 48 53.5 63.1 9.6
South Asia 6 65.2 74.5 9.3
Middle East & North Africa 23 70.1 75.5 5.4
Europe & Central Asia 58 74.1 78.4 4.4
East Asia & Pacific 37 69.4 73.6 4.2
Latin America & Caribbean 42 71.4 74.8 3.4
North America 3 78.0 80.2 2.2
top_region    <- region_summary[1, ]
bottom_region <- region_summary[nrow(region_summary), ]

Insight: Sub-Saharan Africa gained the most life expectancy since 2000, an average of 9.6 years per country (from 53.5 to 63.1). North America gained the least, at 2.2 years.

Insight 2: Gains by Income Group

income_summary <- life %>%
  group_by(income) %>%
  summarize(countries = n(),
            avg_2000  = round(mean(le_2000), 1),
            avg_2022  = round(mean(le_2022), 1),
            avg_gain  = round(mean(gain), 1))

knitr::kable(income_summary,
             col.names = c("Income Group", "Countries", "Avg 2000",
                           "Avg 2022", "Avg Gain (yrs)"))
Income Group Countries Avg 2000 Avg 2022 Avg Gain (yrs)
Low income 25 52.6 62.0 9.4
Lower middle income 47 59.7 67.7 8.0
Upper middle income 59 68.9 73.3 4.5
High income 86 75.4 79.2 3.8
low  <- income_summary %>% filter(income == "Low income")
high <- income_summary %>% filter(income == "High income")

Insight: Low-income countries gained an average of 9.4 years, compared with 3.8 years for high-income countries. The gap between the two groups went from 22.8 years in 2000 to 17.2 years in 2022.

Visualizing Insight 2

ggplot(income_summary, aes(x = income, y = avg_gain, fill = income)) +
  geom_col(show.legend = FALSE) +
  geom_text(aes(label = avg_gain), vjust = -0.5) +
  labs(title = "Average Gain in Life Expectancy, 2000 to 2022",
       subtitle = "By World Bank income group",
       x = NULL, y = "Average gain (years)",
       caption = "Source: World Bank, World Development Indicators") +
  theme_minimal()

Conclusion

Life expectancy rose in every region and income group between 2000 and 2022, but not evenly. The places that started lowest caught up the fastest, which narrowed the gap between rich and poor countries.