Soccer

Sports
Soccer
Analyze clubs, players, matches, goals, standings, and performance across soccer leagues.
Author
Affiliation

Byeong-Hak Choe

SUNY Geneseo

Published

October 6, 2026

Anfield's green soccer pitch and red stands viewed from the main stand.
Anfield, home of Liverpool FC (2019). Photo: Yurificacion / Wikimedia Commons · CC BY-SA 4.0.

Explore the data on a map

Explore the project data by location. Select a location for details.

Loading the map…

Data

On-page tables preview a sample. Each download combines previous and current English Premier League seasons in one CSV at a consistent unit of observation. Updated October 6, 2026.

  • epl_matches: 3,470 completed matches, from 2017–18 through the first five gameweeks of 2026–27.
  • epl_teams: 200 team-season rows over those ten seasons.
  • epl_players: 3,730 player-season rows, from 2021–22 through partial 2026–27.
  • epl_gks: 335 goalkeeper-season rows over those same six seasons.

season_end_year is the year in which the season ends: 2027 means 2026–27. season supplies the display label. is_partial_season == 1 marks the incomplete 2026–27 season. The latest completed match in the source is September 20, 2026. Compare rates per match or per minute when analyzing a partial season alongside completed seasons.

Matches

epl_matches <- read_csv("https://bcdanl.github.io/data/epl_matches.csv")

Each row is one completed fixture, uniquely identified by season_end_year and match_id. All seasons use the same Football-Data results definitions. Club names have been standardized across years. The home_team_id and away_team_id values are normalized versions of those standardized names, shared with the team-season table.

Variables Meaning
match_date, kickoff_time, referee Date, kickoff time where supplied, and referee
home_team, away_team Clubs
home_goals, away_goals Full-time goals
result H = home win, D = draw, A = away win
home_half_goals, away_half_goals, half_result Half-time goals and result
home_shots, away_shots Shots attempted
home_shots_on_target, away_shots_on_target Shots on target
home_fouls, away_fouls Fouls
home_corners, away_corners Corners
home_yellow_cards, away_yellow_cards, home_red_cards, away_red_cards Cards

source_url and retrieved_date record provenance. Betting odds and expected goals with inconsistent availability were dropped from this common match table. Counts are match totals. See the source’s field definitions.

Team seasons

epl_teams <- read_csv("https://bcdanl.github.io/data/epl_teams.csv")

The key is season_end_year and team_id. Every season contains 20 clubs. Completed seasons contain 38 matches per club; 2026–27 currently contains five. Club name is squad.

matches_played, wins, draws, losses, goals, goals_against, and goal_difference summarize the match table. points is three per win plus one per draw and excludes administrative point deductions. Team goals include opponents’ own goals, unlike a sum of goals credited to individual players.

shots, shots_on_target, corners, fouls, yellow_cards, and red_cards sum the same source’s match statistics for every season. Divide totals by matches_played for comparable rates.

The earlier FBref measures remain in the same CSV as fbref_num_players, fbref_age, fbref_poss, fbref_assists, fbref_xg, and fbref_xa. They cover 2017–18 through 2024–25 and are missing afterward. Possession uses a 0–100 percentage scale. The provider prefix distinguishes those definitions from the common Football-Data totals.

Player seasons

epl_players <- read_csv("https://bcdanl.github.io/data/epl_players.csv")

The key is season_end_year and player_id. Each row is a player’s league-season total. Historical FBref team-stint rows are aggregated once per player and season, so players who transferred between EPL clubs are not counted twice. Their squad lists clubs separated by semicolons.

Coverage changes by source and season:

Seasons Source and coverage
2021–22 through 2024–25 Historical FBref players with recorded EPL appearances
2025–26 All 841 players in the final FPL season archive, including players with zero minutes
2026–27 All 667 players listed in the current official FPL snapshot, including zero-minute players

The 2025–26 snapshot comes from Vaastav Anand’s FPL Historical Dataset, pinned to its June 17, 2026 update after gameweek 38. All 480 players also present in the current API’s prior-season history match the archive across 16 fields, including minutes, goals, assists, cards, saves, and fantasy points. Credited goals plus own goals reconcile to the match table’s full season goal total. This archive includes players who left the league before the current season.

FPL snapshots include listed players with zero minutes, whereas historical FBref rows require a recorded appearance. The coverage and source columns identify these differences. Filter to minutes > 0 when comparing participating-player populations. Archived FPL club labels describe the final roster snapshot; a transferred player’s totals cover the whole league season.

player_id uses stable FPL player codes where available. Historical rows share an FPL code only when an exact normalized display/full-name match and equal birth year identify one candidate. Remaining historical rows use a fbref-name: name/birth-year key. These fallback keys are teaching identifiers, not official FBref IDs. Name variants without a verified match remain separate. fpl_season_player_id is the original FPL ID for that row’s season; it can change between seasons. fpl_player_code is the stable source code.

Variables Meaning
player, birth_year, squad, nation, pos Player descriptors where supplied
appearances, starts, minutes Season appearances where supplied, starts, and minutes
goals, yellow_cards, red_cards Season totals
conventional_assists FBref assists, historical rows only
fpl_assists Fantasy assists under FPL scoring rules, FPL rows only
gross_salary_weekly_pound, gross_salary_yearly_pound Historical salary estimates; missing for FPL rows and historical players with multiple clubs
fantasy_price_million_pound FPL game price in millions of pounds; previous-season value is its closing price
fbref_xg, fbref_xa Historical FBref expected goals/assists
fpl_xg, fpl_xa, fpl_xg_conceded FPL expected statistics
fpl_points Fantasy point total
clean_sheets, goals_conceded, own_goals, penalties_saved, penalties_missed, saves FPL season totals

FPL prices describe a fantasy game’s valuation and are not salaries. FPL assists can differ from conventional match assists; the two columns remain separate. Expected statistics also retain their provider names. Do not add these separate fields together or fill one provider’s missing values with another’s. FPL clean-sheet points require at least 60 minutes played without conceding, under the game’s rules.

Historical positions are FBref’s codes such as GK, DF, MF, and FW, including combined positions. Current positions are FPL’s GKP, DEF, MID, and FWD classifications. Historical per-90, progressive-action, and other advanced fields were dropped from the combined player table when they had no comparable current measure. Season totals and minutes allow you to calculate your own rates.

Source: official FPL, its current player endpoint and player-history endpoints, the 2025–26 FPL archive, and the supplied historical FBref EPL tables.

Goalkeeper seasons

epl_gks <- read_csv("https://bcdanl.github.io/data/epl_goalkeepers.csv")

Each row is a goalkeeper’s season total, keyed by season_end_year and player_id. Historical team stints are aggregated. minutes comes from exact player-table totals, rather than multiplying rounded 90-minute units.

The historical goalkeeper field formerly named goals is now goals_conceded: it measures goals allowed, not goals scored. fbref_post_shot_xg and fbref_post_shot_xg_minus_goals retain historical shot-stopping estimates. They are missing in FPL seasons. FPL supplies starts, clean_sheets, saves, penalties_saved, fpl_xg_conceded, fantasy points, and fantasy prices; fields absent from historical tables remain missing.

FPL seasons use each season’s own goalkeeper classification: 97 listed goalkeepers in 2025–26 and 73 in 2026–27. Registered zero-minute goalkeepers remain included. Compare goals allowed and saves alongside minutes played, and respect the coverage differences described above.

Project ideas

  • How do shots and shots on target predict match results over time?
  • Does home advantage vary across seasons?
  • Which clubs improve their points and goal difference per match?
  • How do player goals per 90 minutes vary by role and season?
  • How do fantasy valuations relate to fantasy performance within the FPL cohort?
  • How do goalkeeper goals allowed per 90 minutes change across seasons?

Sports Reference removed its advanced soccer feed in January 2026. Source-specific historical measures remain labeled where retained, and the dated source archives remain available separately from these combined downloads.

Back to top