The modelA gravity model of student flows
We model each origin–destination flow as a gravity-style regression. This is the project's step-3 design: the specification below describes how the collected text and spatial data would be used to answer the research question. It is documented, not estimated.
+ controls(distance, language_affinity)
+ origin FE + destination FE + τt (year FE) + postt·covid_hitj,s + εij
robustness only (exploratory, multicollinear with β1): + gdp_gap, price_level_gap
Tap a term to jump to its evidence section. The β cards lead to the explanatory variables; the controls link lands on the gravity controls block.
The two bilateral frictions distance and language_affinity are the headline gravity controls (low VIF, identifying). gdp_gap and price_level_gap are not in the main spec — they proxy the same rich-vs-poor dimension as salary_gap (VIFs ≈ 5–7) and are kept as an exploratory robustness block. Origin and destination FE absorb broad country-level differences; the estimate is descriptive, not causal.
The βsExplanatory Variables
Each term in the model and its data source. built = data already in the processed pipeline; planned = part of the described design (text layer / rankings / language groupings).
GDP-per-capita gap
Quality of life
Institution quality
Language affinity
Distance
Salary gap
Price-level gap
ResultsModel Results
Every coefficient (β) — headline PPML gravity model
All estimated terms from the cross-sectional PPML model (Poisson on flow level, city-clustered SEs), plus the planned terms not yet built. Significant (p<0.05) in accent. Natural-unit effect is the % change in flow for a tangible unit change — +€1,000 salary gap, +1 Erasmusu rating point, +10 QS score points, doubling distance.
Quality-of-life coefficient across specifications
β₂ across all specs. Outcome is log(1+flow) (OLS/WLS) or flow level (PPML); p-values cluster-robust. Headline: the city-level two-stage (panel destination attractiveness explained by Erasmusu rating).
The same gravity model run on the year panel and through a 2020 shock lives in the Time & Shocks act below.
What we are explaining — the flows themselves
Filter the flows
Picking an 🛫 outgoing university narrows the map and table to flows leaving that institution. Picking an 🛬 incoming country or 🛬 incoming university keeps only flows arriving there. Filters AND-combine: the more you set, the smaller the view.
flowijSelected Country Overview Showing —
Use the sending-country selector in the top bar. Main flow definition: Higher Education learners, study mobility activity, age 18+, cross-border flows only.
flowijUniversity Flow Map Showing —
flowijMobility Over Time (2014–2023) Showing —
Higher Education study mobility by calendar year of mobility start, from the spatially enriched Erasmus+ panel (Väisänen et al. 2025). This is the temporal backbone for the panel gravity design.
All countries — total outgoing
Total cross-border HE study participants per year. The 2020 drop reflects the COVID-19 disruption to mobility.
Selected country — top destinations
Yearly flows from the selected sending country to its largest destinations. Use the sending-country selector in the top bar.
flowijTop Destinations Showing —
flowijDestination table Showing —
flowijFlow Heatmap
Rows and columns use the same country order: countries are sorted by total Erasmus flow volume among the displayed top countries.
What we hold constant — plus an exploratory economics block
β₁ vizGDP Gap and Flow Share Showing —
GDP gap = receiving-country GDP per capita minus sending-country GDP per capita (broad prosperity control, β1). Flow share = flow to that destination divided by all outgoing flows from the selected sending country.
robustnessFlow-Weighted Destination Economics — salary & price-level (robustness)
Reported as robustness, not headline controls. salary_gap and price_level_gap proxy the same rich-vs-poor-destination dimension as the headline gdp_gap (β1): VIFs ≈ 5–7 in the full-controls PPML, so the three monetary gaps split one signal three ways. The full-economic-controls spec is kept here as an exploratory check because of this multicollinearity, not because the economics are uninteresting. See reports/gravity_model.md §4.
Click column headers to sort. Destination metrics are weighted by each sending country's flow counts.
What pulls students toward a destination
β₁GDP-per-capita gap — broad prosperity control
Destination minus origin GDP per capita (World Bank, current USD). Read as a broad prosperity control, not as a causal economic-pull effect. Salary gap and price-level gap are demoted to robustness because they overlap with GDP and produce an unstable monetary block (VIF ~6.5–7 in the full controls spec).
gdp_gap_usd_wb · pair-level destination minus origin, joined onto the KA1 2022 panel.Mean monthly gross earnings by NACE economic sector, Structure of Earnings Survey 2018. This is a salary-by-sector reference, not salary by field of study (Eurostat does not publish earnings by field of study). Coverage is limited to the 17 countries that report this dataset.
β₂Quality of life — perceived liveability
A text layer over r/Erasmus and a numeric layer from Erasmusu city ratings. Tests whether students are pulled toward places that read as friendlier, cheaper, livelier in student talk.
Destination mentions extracted from r/Erasmus posts and comments. Score-weighted net also weights by extraction confidence and log Reddit score. Click headers to sort.
β₃Institution quality — academic pull
Each destination university enters as a ranking score. Tests whether stronger universities pull more inflow once salary gap, distance, and language affinity are held constant.
institution_quality.csv.user_institution_quality.csv.Headline finding: adding institution quality attenuates β₂ by roughly a quarter — perceived liveability and academic pull share signal. See Model Results for the full coefficient table.
The model run through every year — and the 2020 break
panelPanel gravity — year fixed effects (2014–2023)
We refit the gravity PPML on the panel of country-pair flows by year (2014–2023), with origin×destination fixed effects absorbing all time-invariant bilateral pull (distance, language, history, geography) and year fixed effects picking up the common time path. The plotted series is each year's FE relative to 2014 — read it as the log-change in expected flow for any given pair, holding gravity constants fixed.
A flat line would say "Erasmus volume is stable once you control for gravity". Instead we see a steady positive drift through 2019 (program scale-up), the sharp 2020 collapse when borders closed, a partial 2021 rebound, and a return above the 2019 baseline by 2023 — the gravity model says the recovery is real, not a composition artifact of which countries reopened first.
How to read: dot = year FE coefficient · dashed line = 2014 baseline (0) · coral 2020 marker = COVID shock year.
Time-varying regressors — the same gravity model, run year-by-year
When we let a regressor itself vary by year (instead of absorbing time into a single FE), within-destination movement over time identifies it. Three time-varying panels are estimated. Two of the three say something; one says nothing — that null is itself worth reading.
What is a "life-satisfaction point"? The OWID series uses the Cantril ladder from the Gallup World Poll / World Happiness Report: respondents rate their current life on a 0–10 scale ("worst possible life" to "best possible life"). The country score is the mean response. A "+1 life-satisfaction point" means moving the destination's annual mean one full rung up the ladder — e.g. roughly the Spain↔Switzerland gap in 2022. Source: data/processed/owid_country_year.csv.
Read: only life satisfaction identifies cleanly as time-varying — +25.4% per life-satisfaction point, p=0.035. The other two are null. The QS null reflects QS-score stickiness (within-city year-to-year variance is tiny); the education-spending null suggests within-country temporal drift in public-education investment doesn't move Erasmus flows.
shockCOVID-2020 sector DiD on field-level flows
We move from the smooth year-FE path to a real, date-pinned shock. Each ISCED-F broad field of study is mapped to one NACE sector, then we ask: did flows into (destination, field) cells whose mapped sector was hit harder in 2020 fall by more, relative to 2019? We run it twice — once with wage-based hit (LCI), once with employment-based hit (LFS) — because the LCI 2020 series is contaminated by wage-subsidy schemes.
covid_sector_hit.csv — sector wage growth deviation, 2015–2019 baseline. LFS covid_employment_hit.csv — sector employment growth deviation, same baseline. Field → NACE map in src/erasmusgravity/fields.py.How to read: two series of year×hit interactions (2019 as reference). Coral = LCI wage-based hit. Teal = LFS employment-based hit. Filled dots = p<0.05. Dashed horizontal line at zero. Dashed vertical line marks 2019 reference. LCI on a different y-scale from LFS — coefficients in the Effect card read as "% flow change per 1 pp harder hit sector".
NotesData Sources and Measurement Notes
- Erasmus flows:
Erasmus_2014-2023_individual.parquet— the Väisänen et al. (2025) geolocated Erasmus+ dataset (2.46M individual records, LAU and NUTS3 codes on both endpoints). Filtered to Higher Education study mobility; the country-pair cross-section uses mobility year 2022. - Flow scope: Erasmus mobility is modeled as cross-border origin–destination movement. The source covers Erasmus+ programme countries only, so partner-country corridors (US, China, Brazil, Japan, India, …) are out of sample — 60% of country pairs but 4% of flow volume. Those flows run through International Credit Mobility, where places are allocated by grant quota rather than chosen by students.
- University-level flows: still built from
Erasmus-KA1-Mobility-Data-2022.xlsx(sheetKA1 mobilities 2022), not yet migrated to the parquet backbone. Country-level and university-level totals therefore differ. - HE grants:
annual-report-2024-statistical-annex.xlsx, sheetKA1_estimated paxs, Call Year 2022, Higher Education rows. - GDP per capita: World Bank current US$ is used for the dashboard GDP-gap plot because it covers more Erasmus partner countries; Eurostat GDP remains in the processed dataset.
- Price levels and net earnings: Eurostat API. Missing values are shown as
n/a. - Scholarship proxy: grant per participant is applicant-country-level, not the exact grant received by individual students or country pairs. Treat the social-elevator angle as descriptive, not causal.
- Quality of life (built): Reddit
r/Erasmusposts and comments, with destination, sentiment, and themes extracted via OpenRouter (DeepSeek) + Pydantic. Aggregated to per-country net sentiment. Feeds β₂. Per-country counts are small; treat as a qualitative perception layer. - Institution quality (planned): destination university ranking score. Feeds β₃.
- Language affinity (planned): Mediterranean / Anglo-Saxon / Germanic country groupings used as an origin–destination affinity control (gravity friction), not an instrument.