Which regions and business lines receive the largest IFC project budgets, and how have budgets evolved over time? This analysis uses the World Bank/IFC projects dataset provided as a CSV.
# read
raw <- read_csv("ifc_advisory_services_projects_09-21-2025.csv")
# quick glance
dim(raw)
## [1] 2063 15
names(raw)
## [1] "Disclosure Date" "Project Number"
## [3] "Project Name" "Project URL"
## [5] "Country" "IFC Country Code"
## [7] "IFC Region" "Business Line"
## [9] "Estimated Total Budget ($)" "Department"
## [11] "Status" "IFC Approval Date"
## [13] "Projected Start Date" "WB Country Code"
## [15] "As of Date"
head(raw, 5)
## # A tibble: 5 × 15
## `Disclosure Date` `Project Number` `Project Name` `Project URL` Country
## <chr> <dbl> <chr> <chr> <chr>
## 1 03/27/2013 599403 Macedonia Corridor 8… https://disc… North …
## 2 08/14/2025 609003 Ukraine Zhitomir Cit… https://disc… Ukraine
## 3 06/25/2025 608377 Strengthening Logist… https://disc… Ukraine
## 4 04/16/2025 607918 Bolstering the Resil… https://disc… Ukraine
## 5 10/05/2023 608147 Ukrainian Danube Shi… https://disc… Ukraine
## # ℹ 10 more variables: `IFC Country Code` <chr>, `IFC Region` <chr>,
## # `Business Line` <chr>, `Estimated Total Budget ($)` <dbl>,
## # Department <lgl>, Status <chr>, `IFC Approval Date` <chr>,
## # `Projected Start Date` <chr>, `WB Country Code` <chr>, `As of Date` <chr>
Standardize names
Parse dates
Ensure budget is numeric
Keep key columns used in the analysis
df <- raw %>%
clean_names() %>%
rename(
country = country,
region = ifc_region,
business_line = business_line,
budget_usd = estimated_total_budget
) %>%
mutate(
ifc_approval_date = mdy(ifc_approval_date),
projected_start_date = suppressWarnings(mdy(projected_start_date)),
year = year(ifc_approval_date),
# Some files label currency as "Estimated Total Budget ($)"
budget_usd = as.numeric(budget_usd)
) %>%
select(disclosure_date, project_number, project_name, country, region,
business_line, budget_usd, status, ifc_approval_date, year)
# basic NA handling for budget (drop rows without budget for budget analysis)
df_budget <- df %>% drop_na(budget_usd)
summary(df_budget$budget_usd)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0 368654 900000 1483249 2000000 60000000
# projects by region
projects_by_region <- df %>%
count(region, sort = TRUE)
kable(projects_by_region, caption = "Project Count by IFC Region")
| region | n |
|---|---|
| Africa | 774 |
| East Asia and the Pacific | 307 |
| South Asia | 273 |
| Latin America and the Caribbean | 226 |
| Middle East | 157 |
| Europe | 148 |
| Global | 90 |
| Central Asia and Turkiye | 88 |
# projects by business line
projects_by_line <- df %>%
count(business_line, sort = TRUE)
kable(projects_by_line, caption = "Project Count by Business Line")
| business_line | n |
|---|---|
| Financial Institutions Group | 402 |
| Other | 374 |
| Access To Finance | 203 |
| Transaction Advisory | 194 |
| Manufacturing, Agribusiness & Services | 167 |
| Infrastructure | 109 |
| Investment Climate | 92 |
| Sustainable Business Advisory | 85 |
| Cross-Industry Advisory Services | 72 |
| Public-Private Partnerships Transaction Advisory | 68 |
| Environment, Social and Governance | 61 |
| Trade and Competitiveness | 58 |
| NA | 42 |
| Finance and Markets | 35 |
| Corporate Advice | 24 |
| Infrastructure and Natural Resources | 21 |
| Business Enabling Environment | 17 |
| Global Practice - Trade & Competitiveness | 13 |
| Industry Department - Financial Institutions Group | 8 |
| Pending | 6 |
| PrimaryBusinessArea Pending | 6 |
| Global Practice - Finance & Markets | 5 |
| Environment and Social Sustainability | 1 |
avg_budget_region <- df_budget %>%
group_by(region) %>%
summarize(
average_budget_usd = mean(budget_usd, na.rm = TRUE),
median_budget_usd = median(budget_usd, na.rm = TRUE),
projects = n()
) %>%
arrange(desc(average_budget_usd))
kable(avg_budget_region %>%
mutate(across(contains("budget"), dollar)),
caption = "Average & Median Project Budget by Region (USD)")
| region | average_budget_usd | median_budget_usd | projects |
|---|---|---|---|
| Global | $3,596,212 | $2,353,813 | 90 |
| Europe | $2,246,933 | $1,837,500 | 148 |
| Central Asia and Turkiye | $1,455,298 | $977,630 | 88 |
| Latin America and the Caribbean | $1,390,204 | $698,900 | 226 |
| Africa | $1,378,276 | $854,000 | 774 |
| East Asia and the Pacific | $1,316,306 | $991,000 | 307 |
| Middle East | $1,142,113 | $800,000 | 157 |
| South Asia | $1,140,225 | $640,613 | 273 |
total_by_line <- df_budget %>%
group_by(business_line) %>%
summarize(
total_budget_usd = sum(budget_usd, na.rm = TRUE),
projects = n()
) %>%
arrange(desc(total_budget_usd))
kable(total_by_line %>%
mutate(total_budget_usd = dollar(total_budget_usd)),
caption = "Total Budget by Business Line (USD)")
| business_line | total_budget_usd | projects |
|---|---|---|
| Other | $615,987,166 | 374 |
| Access To Finance | $414,981,651 | 203 |
| Financial Institutions Group | $303,801,837 | 402 |
| Transaction Advisory | $267,569,921 | 194 |
| Manufacturing, Agribusiness & Services | $227,379,616 | 167 |
| Investment Climate | $194,044,421 | 92 |
| Infrastructure | $176,105,141 | 109 |
| Sustainable Business Advisory | $164,280,443 | 85 |
| Trade and Competitiveness | $123,431,058 | 58 |
| Cross-Industry Advisory Services | $118,681,763 | 72 |
| Corporate Advice | $85,505,638 | 24 |
| Environment, Social and Governance | $76,055,433 | 61 |
| Public-Private Partnerships Transaction Advisory | $75,293,730 | 68 |
| Infrastructure and Natural Resources | $57,545,254 | 21 |
| Business Enabling Environment | $56,334,382 | 17 |
| Finance and Markets | $43,755,867 | 35 |
| Global Practice - Trade & Competitiveness | $29,295,551 | 13 |
| Environment and Social Sustainability | $10,300,000 | 1 |
| Pending | $6,929,843 | 6 |
| PrimaryBusinessArea Pending | $4,740,909 | 6 |
| Global Practice - Finance & Markets | $4,734,139 | 5 |
| Industry Department - Financial Institutions Group | $3,188,353 | 8 |
| NA | $0 | 42 |
Insight 2 (preview): A few business lines dominate total investment volume. Others may have more projects but smaller budgets per project.
avg_budget_region %>%
ggplot(aes(x = reorder(region, average_budget_usd),
y = average_budget_usd)) +
geom_col() +
coord_flip() +
scale_y_continuous(labels = label_dollar()) +
labs(title = "Average IFC Project Budget by Region",
x = "IFC Region",
y = "Average Budget (USD)") +
theme_minimal(base_size = 12)
df_budget %>%
filter(!is.na(year)) %>%
ggplot(aes(x = year, y = budget_usd)) +
geom_point(alpha = 0.4) +
geom_smooth(se = FALSE) +
scale_y_continuous(labels = label_dollar(scale = 1e-6, suffix = "M")) +
labs(title = "Evolution of IFC Project Budgets",
subtitle = "IFC approval year vs. project budget",
x = "Approval Year",
y = "Budget (Million USD)") +
theme_minimal(base_size = 12)