The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Fast, tidy Pro Golf data in R
golfastr provides easy access to professional golf data
from ESPN with functions to get leaderboards and hole-by-hole scores in
tidy data formats ready for analysis. Supports PGA
Tour, LIV Golf, LPGA,
DP World Tour, and Champions Tour.
# Install from CRAN
install.packages("golfastr")
# Or install development version from GitHub
# install.packages("pak")
pak::pak("array-carpenter/golfastr")| Tour | Code | Example |
|---|---|---|
| PGA Tour | "pga" |
load_schedule(2026, tour = "pga") |
| LIV Golf | "liv" |
load_schedule(2026, tour = "liv") |
| LPGA | "lpga" |
load_schedule(2026, tour = "lpga") |
| DP World Tour | "euro" |
load_schedule(2026, tour = "euro") |
| Champions Tour | "champions" |
load_schedule(2026, tour = "champions") |
All functions accept the tour parameter. Default is
"pga".
library(golfastr)
# Get the PGA tournament schedule
schedule <- load_schedule(2026)
# Load a tournament leaderboard
sony <- load_leaderboard(2026, "Sony")
# Get hole-by-hole scoring for top 10
holes <- load_holes(2026, "Sony", top_n = 10)
# LIV Golf works the same way
liv_schedule <- load_schedule(2026, tour = "liv")
adelaide <- load_leaderboard(2026, "Adelaide", tour = "liv")Completed PGA Tour tournaments are served from pre-built data files hosted on GitHub releases, updated daily. This makes loading a full season near-instant and provides hole-by-hole data for the full field, not just the top finishers:
# Loads from hosted data - seconds, not minutes
season <- load_leaderboard(2025)
# Full-field hole-by-hole scoring
holes <- load_holes(2025, "Masters")
# Bypass hosted data for in-progress tournaments
live_lb <- load_leaderboard(2026, "Travelers", live = TRUE)If the hosted data is unavailable (or a tournament is still in progress), both functions automatically fall back to the live ESPN API.
Pre-built PGA Tour strokes gained data ships with the package:
# Latest strokes gained (downloads if needed; bundled data is the fallback)
sg <- load_strokes_gained()
# One player in one season, no network
load_strokes_gained("Scheffler", use_bundled = TRUE, year = 2026)Returns per-round averages for all six SG categories:
| Field | Description |
|---|---|
| sg_putt | Strokes Gained: Putting |
| sg_arg | Strokes Gained: Around the Green |
| sg_app | Strokes Gained: Approach the Green |
| sg_ott | Strokes Gained: Off the Tee |
| sg_t2g | Strokes Gained: Tee to Green |
| sg_total | Strokes Gained: Total |
Every PGA Tour stroke since 2012, plus tee times and course setup by round:
shots <- load_shots(2026, "Masters")
tee_times <- load_tee_times(2026, "Masters")
setup <- load_course_setup(2026, "Masters")
# Strokes gained for every shot, then totals by round
sg <- calculate_strokes_gained(shots)
summarise_strokes_gained(sg, by = "round")load_holes() files carry win_prob,
win_prob_before, wpa and
skill_rating for every PGA Tour stroke play event since
2004. add_win_probability() computes them for an event in
progress.
# ESPN to PGA Tour ID crosswalk
load_player_ids("Scheffler")
load_event_ids(2026)
# Logo image URLs for tours, tournaments, courses and clubs
load_logos("club", "Augusta")
# What's in the bag: equipment by club, and switches
load_witb("Scheffler", year = 2026, slot = "putter")
# Build or refresh a local SQLite database
update_db(dbdir = "~/golf")# Get schedule for a season
schedule <- load_schedule(2026)
# LIV Golf schedule
liv <- load_schedule(2026, tour = "liv")
# Returns: event_id, tournament_name, start_date, end_date# Load by tournament name (partial match)
masters <- load_leaderboard(2026, "Masters")
phoenix <- load_leaderboard(2026, "Phoenix")
# Load by event ID
lb <- load_leaderboard(2026, "401703504")
# Load all tournaments for the year
all_lb <- load_leaderboard(2026)
# LIV Golf leaderboard
liv_lb <- load_leaderboard(2026, "Adelaide", tour = "liv")# Get scorecards for top finishers
holes <- load_holes(2026, "Sony", top_n = 10)
# Returns: player_id, player_name, round, hole, par, score, score_type# Get players from recent tournaments
players <- load_players(2026)| Field | Description |
|---|---|
| position | Final standing |
| player_id | ESPN athlete ID |
| player_name | Player display name |
| total_score | Total strokes |
| score_to_par | Score vs par as text (e.g., “-11”, "E" for even
par) |
| status | Player status |
| Field | Description |
|---|---|
| position | Final leaderboard standing |
| round | Round number (1-4) |
| hole | Hole number (1-18) |
| par | Par for hole |
| score | Strokes on hole |
| score_type | BIRDIE, PAR, BOGEY, EAGLE, etc. |
Store data locally for faster repeated access:
# Save to RDS (native R format)
save_to_rds(leaderboard_data, file_path = "golf_data.rds")
# Load from RDS
data <- load_from_rds(file_path = "golf_data.rds")
# Or use Parquet for cross-language compatibility (requires arrow)
save_to_parquet(leaderboard_data, file_path = "golf_data.parquet")
data <- load_from_parquet(file_path = "golf_data.parquet")
# Auto-detect format with load_data()
data <- load_data("golf_data.rds")
data <- load_data("golf_data.parquet", tournament = "Masters")# Incrementally fetch all tournaments for a season
build_season(2025, file_path = "pga_2025.rds")
# Check progress
check_season(2025, file_path = "pga_2025.rds")Pass a tibble from load_leaderboard(), or a file saved
with save_to_rds():
season <- load_leaderboard(2025)
player_summary("Scheffler", data = season)
compare_players(c("Scheffler", "McIlroy"), data = season)
win_leaders(data = season)
scoring_avg_leaders(data = season)Tournament data is sourced from ESPN’s Golf API (https://www.espn.com/golf/). Strokes gained data is sourced from the PGA Tour (https://www.pgatour.com/stats).
MIT
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.