# Economic Capacity and Donor Generosity: Determinants of Bilateral Aid to Ukraine
# Research Question: Since Russia’s full-scale invasion of Ukraine in 2022, governments worldwide have provided military, financial, and humanitarian support—but the scale and distribution of that support vary dramatically across countries. My central question is: how do donor characteristics—especially economic size, EU membership, and geographic proximity—explain cross-country differences in bilateral aid commitments to Ukraine?
# Hypothesis: I expect that countries with larger economies will commit more bilateral aid because they possess greater fiscal and institutional capacity. I also anticipate that geographic proximity will matter: European states are likely to contribute more due to higher security exposure and stronger political stakes. At the same time, EU membership may reduce recorded bilateral commitments for some countries, since part of their assistance is channeled through EU institutions rather than reported as national bilateral aid. Overall, I predict that GDP will be the strongest predictor, with proximity and institutional factors exerting meaningful but secondary influence.

# Why it Matters?: Understanding who actually finances aid to Ukraine is crucial for informed public debate and fair burden-sharing. Political claims about “hundreds of billions” in U.S. assistance have circulated widely—for instance, President Donald Trump in early 2025 said the United States had provided “over $300 billion” in wartime aid. However, fact-checked data from the Kiel Institute for the World Economy show that U.S. commitments totaled roughly $134 billion from January 2022 through June 2025, far below that figure. These discrepancies underscore the need for careful, data-driven analysis. By identifying how economic capacity, regional exposure, and institutional arrangements shape aid patterns, this project contributes clearer evidence to debates on international solidarity, policy design, and accountability—helping policymakers, journalists, and citizens understand who is contributing, and by how much.
# Load all necessary packages 
library(readxl)       # to import Excel sheets
library(dplyr)        # data cleaning and manipulation
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(tidyr)        # data reshaping
library(ggplot2)      # visualizations
library(stargazer)    # summary statistics tables
## 
## Please cite as:
##  Hlavac, Marek (2022). stargazer: Well-Formatted Regression and Summary Statistics Tables.
##  R package version 5.2.3. https://CRAN.R-project.org/package=stargazer
library(janitor)      # cleaning messy column names
## 
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
library (broom)       # cleaning 
# Load and Clean dataset
# Load and clean the dataset
metrix_data <- read_excel("Econometrics_finalproject.xlsx")
## New names:
## • `Total bilateral allocations` -> `Total bilateral allocations...7`
## • `Total bilateral commitments` -> `Total bilateral commitments...11`
## • `GDP (2021)` -> `GDP (2021)...12`
## • `GDP (2021)` -> `GDP (2021)...13`
## • `Total bilateral commitments` -> `Total bilateral commitments...14`
## • `Total bilateral allocations` -> `Total bilateral allocations...15`
## • `Share in total EU commitments` -> `Share in total EU commitments...18`
## • `Share in total EU commitments` -> `Share in total EU commitments...19`
## • `Total bilateral and EU assistance` -> `Total bilateral and EU
##   assistance...20`
## • `Total bilateral and EU assistance` -> `Total bilateral and EU
##   assistance...21`
## • `Total bilateral commitments (short term)` -> `Total bilateral commitments
##   (short term)...27`
## • `Total bilateral commitments (short term)` -> `Total bilateral commitments
##   (short term)...28`
## • `Share in total EU allocations` -> `Share in total EU allocations...31`
## • `Share in total EU allocations` -> `Share in total EU allocations...32`
## • `Total bilateral and EU allocations` -> `Total bilateral and EU
##   allocations...33`
## • `Total bilateral and EU allocations` -> `Total bilateral and EU
##   allocations...34`
# Clean column names for easier reference
country_clean <- metrix_data %>% 
  clean_names()

# Display cleaned column names
names(country_clean)
##  [1] "country"                                    
##  [2] "eu_member"                                  
##  [3] "geographic_europe"                          
##  [4] "financial_allocations"                      
##  [5] "humanitarian_allocations"                   
##  [6] "military_allocations"                       
##  [7] "total_bilateral_allocations_7"              
##  [8] "financial_commitments"                      
##  [9] "humanitarian_commitments"                   
## [10] "military_commitments"                       
## [11] "total_bilateral_commitments_11"             
## [12] "gdp_2021_12"                                
## [13] "gdp_2021_13"                                
## [14] "total_bilateral_commitments_14"             
## [15] "total_bilateral_allocations_15"             
## [16] "share_in_eu_commitments"                    
## [17] "share_in_eib_commitments"                   
## [18] "share_in_total_eu_commitments_18"           
## [19] "share_in_total_eu_commitments_19"           
## [20] "total_bilateral_and_eu_assistance_20"       
## [21] "total_bilateral_and_eu_assistance_21"       
## [22] "specific_weapons_and_equipment"             
## [23] "financial_commitments_with_military_purpose"
## [24] "financial_commitments_short_term"           
## [25] "humanitarian_commitments_short_term"        
## [26] "military_commitments_short_term"            
## [27] "total_bilateral_commitments_short_term_27"  
## [28] "total_bilateral_commitments_short_term_28"  
## [29] "share_in_eu_allocations"                    
## [30] "share_in_eib_allocations"                   
## [31] "share_in_total_eu_allocations_31"           
## [32] "share_in_total_eu_allocations_32"           
## [33] "total_bilateral_and_eu_allocations_33"      
## [34] "total_bilateral_and_eu_allocations_34"
# For my project I use the “Country Summary ($)” sheet from the Ukraine Support Tracker (Kiel Institute, October 2025 update). The Tracker records government-to-government support provided to Ukraine across 41 donor countries from January 24, 2022 through October 31, 2025. It reports commitments in billions of USD and separates them into military, financial, and humanitarian categories. The dataset excludes private donations, NGO transfers, and assistance from international organizations because these sources do not have consistent reporting. Since this project is based on a cross-section, each row represents one donor country and all commitments reflect cumulative totals over the period.
# Varibales Used in my Analysis:
# a) Total Bilateral Commitments (Dependent Variable): The sum of military, financial, and humanitarian commitments made directly by each donor government.
# b)GDP (2021) (Key Explanatory Variable): Measured in USD billions; used as a pre-war and comparable measure of economic size.
# c) EU Membership: A variable indicating whether a country is part of the European Union.
# d) Geographic Europe: A variable identifying whether a country is located in the broader European region; used as a proxy for geographic proximity and security exposure.
# Create variable table
variable_table <- data.frame(
  Variables = c("country",
                "total_bilateral_commitments_11",
                "gdp_2021_12",
                "eu_member",
                "geographic_europe"),
  
  n = c(
    sum(!is.na(country_clean$country)),
    sum(!is.na(country_clean$total_bilateral_commitments_11)),
    sum(!is.na(country_clean$gdp_2021_12)),
    sum(!is.na(country_clean$eu_member)),
    sum(!is.na(country_clean$geographic_europe))
  ),
  
  source = rep("Kiel Institute – Country Summary", 5)
)

variable_table
##                        Variables  n                           source
## 1                        country 43 Kiel Institute – Country Summary
## 2 total_bilateral_commitments_11 43 Kiel Institute – Country Summary
## 3                    gdp_2021_12 43 Kiel Institute – Country Summary
## 4                      eu_member 42 Kiel Institute – Country Summary
## 5              geographic_europe 42 Kiel Institute – Country Summary
# Summary Statistics
sg_data <- country_clean %>%
  select(total_bilateral_commitments_11, gdp_2021_12, eu_member, geographic_europe) %>%
  drop_na() %>%
  as.data.frame()

stargazer(
  sg_data,
  type = "text",
  title = "Summary Statistics for Key Variables",
  digits = 2,
  summary.stat = c("n", "mean", "sd", "min", "max")
)
## 
## Summary Statistics for Key Variables
## ===================================================================
## Statistic                      N    Mean   St. Dev.  Min     Max   
## -------------------------------------------------------------------
## total_bilateral_commitments_11 42  11.65    27.69   0.002  135.61  
## gdp_2021_12                    42 2,265.64 5,013.21 17.36 23,315.08
## eu_member                      42   0.64     0.48     0       1    
## geographic_europe              42   0.76     0.43     0       1    
## -------------------------------------------------------------------
# After importing the dataset, I cleaned the variable names, removed duplicate columns, and ensured that all numeric fields were properly formatted. The final analytical dataset contains 42 complete observations for all core variables used in the regression. I also generated a variable table to confirm the number of non-missing values and produced summary statistics—including means, minimums, maximums, and standard deviations—to provide an overview of aid levels and donor characteristics.

# The summary statistics indicate substantial cross-country variation in support for Ukraine. Total bilateral commitments range from nearly zero to 135.6 billion USD, with a mean of 11.65 billion, suggesting that a small number of major donors account for most of the total aid while many countries contribute relatively modest amounts. GDP shows a similarly wide spread, with values ranging from very small economies to extremely large ones, reflected in a high standard deviation of 5,013 billion USD.

# The binary indicators show that 64% of countries in the sample are EU members and 76% are geographically European, confirming that most donors have strong regional or institutional ties to Ukraine. Overall, the large variation in both aid commitments and GDP, combined with the distribution of EU and geographic indicators, suggests meaningful potential relationships between donor capacity, proximity, and bilateral aid generosity
cov_matrix <- country_clean %>%
  select(total_bilateral_commitments_11, gdp_2021_12, eu_member, geographic_europe) %>%
  cov(use = "complete.obs")

cov_matrix
##                                total_bilateral_commitments_11   gdp_2021_12
## total_bilateral_commitments_11                     766.807574   111175.1470
## gdp_2021_12                                     111175.147013 25132252.9811
## eu_member                                           -4.458506    -1073.0446
## geographic_europe                                   -1.494250     -822.0929
##                                    eu_member geographic_europe
## total_bilateral_commitments_11    -4.4585064        -1.4942495
## gdp_2021_12                    -1073.0446054      -822.0928826
## eu_member                          0.2351916         0.1567944
## geographic_europe                  0.1567944         0.1858304
# The covariance matrix shows how each pair of variables moves together in absolute terms. The large positive covariance between GDP and total bilateral aid suggests that countries with higher GDP usually give larger amounts of aid. The number is very large mainly because both variables are measured in billions, so their scale affects the covariance.

# The negative covariances between GDP and the two binary variables (EU membership and geographic Europe) are not very meaningful by themselves. They mostly reflect that some of the highest-GDP countries in the dataset—such as the United States and Japan—are not located in Europe and are not EU members. The small positive covariance between EU membership and geographic Europe is expected because most EU members are also geographically in Europe. Overall, the covariance matrix indicates that GDP is the variable most strongly associated with aid levels, while the binary indicators show much weaker raw relationships. These patterns are examined more formally in the regression analysis.
# Simple regression: aid on GDP
model_simple <- lm(total_bilateral_commitments_11 ~ gdp_2021_12,
                   data = sg_data)

summary(model_simple)
## 
## Call:
## lm(formula = total_bilateral_commitments_11 ~ gdp_2021_12, data = sg_data)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -80.069  -2.710  -1.710   1.347  35.157 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 1.622973   2.848835   0.570    0.572    
## gdp_2021_12 0.004424   0.000523   8.458 1.92e-10 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 16.79 on 40 degrees of freedom
## Multiple R-squared:  0.6414, Adjusted R-squared:  0.6324 
## F-statistic: 71.53 on 1 and 40 DF,  p-value: 1.916e-10
# The simple regression shows a clear and strong positive relationship between GDP and bilateral aid commitments. The GDP coefficient is about 0.0044, which means that for every additional $1 billion in GDP, a country gives roughly $4.4 million more in bilateral aid. This effect is highly statistically significant, with a p-value close to zero. The model explains about 64% of the variation in aid levels, which is fairly high for a regression with only one explanatory variable. The intercept is not significant, but that is not very important because no country in the dataset has a GDP near zero. Overall, the results strongly support the idea that countries with larger economies tend to give more aid to Ukraine.
# 95% Confidence Interval for GDP coefficient
confint(model_simple)
##                    2.5 %      97.5 %
## (Intercept) -4.134738524 7.380684103
## gdp_2021_12  0.003366512 0.005480697
# The 95% confidence interval for the GDP coefficient ranges from 0.00337 to 0.00548, meaning the effect of GDP on bilateral aid is positive and estimated with good precision. Since the whole interval is above zero, it confirms that higher GDP is consistently linked to higher aid commitments. Even at the low end, an extra $1 billion in GDP is associated with at least $3.3 million more in aid, and at the high end, about $5.5 million. The interval is also fairly tight, which suggests that the relationship is stable and not driven by outliers. Overall, the confidence interval strengthens the conclusion that richer countries tend to give more aid to Ukraine.
# Multiple regression: adding EU + geographic Europe
model_multiple <- lm(total_bilateral_commitments_11 ~ gdp_2021_12 +
                       eu_member + geographic_europe,
                     data = sg_data)
summary(model_multiple)
## 
## Call:
## lm(formula = total_bilateral_commitments_11 ~ gdp_2021_12 + eu_member + 
##     geographic_europe, data = sg_data)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -73.618  -2.724  -1.513   4.717  36.225 
## 
## Coefficients:
##                     Estimate Std. Error t value Pr(>|t|)    
## (Intercept)       -8.248e+00  5.827e+00  -1.415  0.16510    
## gdp_2021_12        4.616e-03  5.454e-04   8.465 2.83e-10 ***
## eu_member         -1.406e+01  7.882e+00  -1.783  0.08256 .  
## geographic_europe  2.424e+01  8.604e+00   2.817  0.00764 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 15.65 on 38 degrees of freedom
## Multiple R-squared:  0.7038, Adjusted R-squared:  0.6804 
## F-statistic:  30.1 on 3 and 38 DF,  p-value: 3.879e-10
# The multiple regression shows that GDP is still a very strong and significant predictor of bilateral aid, even after adding EU membership and geographic Europe. The GDP coefficient is almost the same as in the simple regression, which means that the effect of economic size is not explained away by political or geographic factors. It remains a central driver of how much countries give. 

# Geographic Europe is also significant. The coefficient suggests that countries located in Europe give about 24 billion USD more in bilateral aid than non-European countries, after controlling for GDP. This makes sense because European states are closer to the conflict and have stronger security incentives to support Ukraine. EU membership has a negative coefficient and is only borderline significant. This likely reflects reporting differences: many EU members send a large share of their support through EU institutions instead of counting it as their own bilateral aid, which makes their national numbers look smaller. The model explains about 70% of the variation in bilateral aid, which is strong for cross-country data. Overall, the results show that economic size and geographic proximity matter the most, while EU membership affects the form of aid rather than the total level countries actually contribute.
# Finally, let's conduct an F-test
# Restricted model (GDP only)
restricted <- lm(total_bilateral_commitments_11 ~ gdp_2021_12,
                 data = sg_data)

# Unrestricted model (GDP + controls)
unrestricted <- model_multiple

# Compute F-statistic
anova(restricted, unrestricted)
## Analysis of Variance Table
## 
## Model 1: total_bilateral_commitments_11 ~ gdp_2021_12
## Model 2: total_bilateral_commitments_11 ~ gdp_2021_12 + eu_member + geographic_europe
##   Res.Df     RSS Df Sum of Sq      F Pr(>F)  
## 1     40 11275.5                             
## 2     38  9312.4  2    1963.2 4.0054 0.0264 *
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# The F-test compares the simple regression with only GDP to the fuller model that adds EU membership and geographic Europe. The p-value is 0.026, which is below the 5% level, so I reject the null hypothesis that the extra variables have no joint effect. This means that adding EU membership and geographic proximity improves the overall explanatory power of the model. Even though GDP remains the main driver of aid levels, the F-test shows that political and regional factors still contribute meaningful additional information. This supports using the multiple regression as the main specification instead of relying only on GDP.

# Finally, my analysis shows that economic size is the strongest predictor of how much bilateral aid countries commit to Ukraine. Richer countries consistently give more, which fits the idea that greater fiscal capacity leads to higher support. Geographic proximity also matters, as countries in Europe tend to contribute more even after controlling for GDP, likely since they face higher security risks from the war. EU membership has a more complicated effect because many EU states channel aid through EU institutions rather than reporting it as national bilateral aid. Together, the results suggest that both material capacity and regional context shape donor behavior.