Efficiently Access Pro Golf Data

Designed for quickly grabbing PGA Tour data. Includes a large data update with shot-level PGA Tour 'ShotLink' data, tee times and course setup, strokes gained, win probability after every hole, a what's in the bag database (WITBDB) of player equipment, an ID crosswalk between 'ESPN' and the PGA Tour, and logo image URLs. Leaderboards and hole-by-hole scoring come from 'ESPN' < https://www.espn.com/golf/> for the PGA Tour, LIV Golf, LPGA, DP World Tour and Champions Tour. Completed seasons are served from hosted files for fast repeated access, and data can be saved as RDS, 'Apache Arrow' Parquet or a 'SQLite' database.


golfastr golfastr logo

CRAN status CRAN downloads R-CMD-check

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.

Installation

# Install from CRAN
install.packages("golfastr")

# Or install development version from GitHub
# install.packages("pak")
pak::pak("array-carpenter/golfastr")

Supported Tours

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".

Quick Start

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")

Hosted Data

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.

Strokes Gained

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

ShotLink

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")

Win Probability

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.

IDs, Logos and a Local Database

# 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")

Core Functions

Tournament Schedule

# 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

Leaderboards

# 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")

Hole-by-Hole Scoring

# Get scorecards for top finishers
holes <- load_holes(2026, "Sony", top_n = 10)

# Returns: player_id, player_name, round, hole, par, score, score_type

Player Directory

# Get players from recent tournaments
players <- load_players(2026)

Data Schema

Leaderboard

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

Hole-by-Hole

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.

Local Storage

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")

Build a Season Database

# 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")

Analysis Functions

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)

Data Source

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).

License

MIT

Reference manual

It appears you don't have a PDF plugin for this browser. You can click here to download the reference manual.

install.packages("golfastr")

0.3.0 by Ray Carpenter, 7 days ago


https://golfastr.com/, https://github.com/array-carpenter/golfastr


Report a bug at https://github.com/array-carpenter/golfastr/issues


Browse source code at https://github.com/cran/golfastr


Authors: Ray Carpenter [aut, cre, cph]


Documentation:   PDF Manual  


MIT + file LICENSE license


Imports httr2, dplyr, tibble, lifecycle, cli

Suggests testthat, arrow, DBI, ggplot2, RSQLite


See at CRAN