Access Men's Basketball Play by Play Data
Overview
A utility to quickly obtain clean and tidy men's basketball play by play data. Provides functions to access live play by play and box score data from ESPNhttps://www.espn.com with shot locations when available. It is also a full NBA Stats APIhttps://www.nba.com/stats/ wrapper. It is also a scraping and aggregating interface for Ken Pomeroy's men's college basketball statistics websitehttps://kenpom.com. It provides users with an active subscription the capability to scrape the website tables and analyze the data for themselves.
Development release on top of the CRAN-shipped 3.0.0 (commit
b76100b3).
Headline change is a **58-wrapper ESPN endpoint expansion** that brings
hoopR's ESPN coverage to parity with wehoop — athlete coverage, team
detail, event detail, league catalog, news, calendar, injuries, plus
draft / freeagents / transactions for the NBA. Also includes bug fixes
for endpoint behavior that drifted after CRAN submission, the
package-wide @return documentation upgrade, and a proxy-support
restoration that addresses a regression introduced by the 3.0.0
httr → httr2 migration.
**NBA cross-source crosswalks (nba_*_crosswalk + load_nba_*_crosswalk)**
New convenience functions that link team / schedule / player identities across
Show all changes in 3.1.0Hide the rest of the changes in 3.1.0
ESPN, the NBA Stats API, and Fox Sports on a shared espn_team_id key:
nba_team_crosswalk(), nba_schedule_crosswalk() (joins on the local
Eastern-Time game date), and nba_player_crosswalk() (ESPN-anchored
deterministic fuzzy matching), each paired with a load_nba_*_crosswalk()
cached loader. Adds fox_nba_teams() / fox_mbb_teams() deriving the Fox team
directory from the standings endpoint. A shared internal .bb_* matching engine
(R/crosswalk_basketball.R) backs the builders.
**MBB cross-source crosswalks (mbb_*_crosswalk + load_mbb_*_crosswalk)**
New convenience functions that link team / schedule / player identities across
ESPN, KenPom (teams_links bundled data — no auth required), Bart Torvik
(barttorvik.com), and Fox Sports on a shared espn_team_id key:
mbb_team_crosswalk(), mbb_schedule_crosswalk() (joins on ET game date via
Torvik's game schedule), and mbb_player_crosswalk() (ESPN-anchored
deterministic fuzzy matching vs. Fox), each paired with a
load_mbb_*_crosswalk() cached loader. Torvik and KenPom team names are
bridged to ESPN via curated alias tables (.mbb_bart_alias, .mbb_kp_alias)
and a .bb_normalize_college_team() contracting normalizer (expands
State/Saint abbreviations). Fox names are bridged via .mbb_fox_display_alias.
Adds fox_mbb_teams_all() to enumerate the full MBB Fox Bifrost team
directory (conference-seed walking). Backed by the shared .bb_* engine in
R/crosswalk_basketball.R.
**Fox Sports basketball wrappers (fox_nba_* / fox_mbb_*)**
Read-only Fox Sports "Bifrost" basketball wrappers over
api.foxsports.com/bifrost/v1/{nba,cbk}/*, complementing the espn_nba_* /
espn_mbb_* families. Eight wrappers per league flatten Fox's layout-oriented
JSON (sections → tables → rows → cells) into tidy hoopR_data tibbles:
fox_<lg>_pbp (period-based play-by-play), _boxscore, _odds,
_team_roster, _team_stats, _team_gamelog, _standings,
_league_leaders. A shared internal layer backs both leagues. Verified live;
reverse-engineering notes + an OpenAPI 3.1 spec live in the sdv-internal-refs
repo. Parallels the cfbfastR / sportsdataverse-py fox_* families.
**CollegeBasketballData API (cbbd_*)**
New cbbd_*() function family wrapping the
CollegeBasketballData API (the men's
college basketball sibling of CollegeFootballData, which cfbfastR wraps with
cfbd_*). 38 endpoint wrappers cover the full v1 surface across 13 categories:
- **Games**:
cbbd_games(),cbbd_games_media(),cbbd_games_teams(),cbbd_games_players(),cbbd_scoreboard() - **Plays**:
cbbd_plays_game(),cbbd_plays_player(),cbbd_plays_team(),cbbd_plays_date(),cbbd_plays_tournament(),cbbd_play_types() - **Substitutions**:
cbbd_substitutions_game(),cbbd_substitutions_player(),cbbd_substitutions_team() - **Stats**:
cbbd_stats_team_season(),cbbd_stats_team_leaderboard(),cbbd_stats_team_shooting_season(),cbbd_stats_player_season(),cbbd_stats_player_shooting_season() - **Lineups**:
cbbd_lineups_team(),cbbd_lineups_game() - **Ratings**:
cbbd_ratings_srs(),cbbd_ratings_adjusted(),cbbd_ratings_elo() - **Rankings**:
cbbd_rankings() - **Lines**:
cbbd_lines(),cbbd_lines_providers() - **Recruiting**:
cbbd_recruiting_players(),cbbd_recruiting_teams(),cbbd_recruiting_portal() - **Draft**:
cbbd_draft_teams(),cbbd_draft_positions(),cbbd_draft_picks() - **Teams / Venues / Conferences**:
cbbd_teams(),cbbd_teams_roster(),cbbd_venues(),cbbd_conferences(),cbbd_conferences_history()
The API requires a free Bearer-token key stored in the CBBD_API_KEY
environment variable; see ?register_cbbd. Helpers cbbd_key(),
has_cbbd_key() and check_cbbd_key() mirror the cfbfastR key pattern. Every
wrapper returns a hoopR_data tibble with a 3-column @return table, routes
through hoopR's shared httr2 request layer (retries / timeouts / proxy), and
reports errors via the standard cli reporters.
**Bart Torvik / T-Rank (torvik_*)**
New torvik_*() function family pulling publicly available men's college
basketball data directly from barttorvik.com — no
account or API key required (analogous to how kp_* scrapes KenPom). These wrap
the auth-free, self-describing data files (the interactive .php pages behind
barttorvik's JavaScript browser check are intentionally avoided):
- **
torvik_ratings()** — year-end / current T-Rank team ratings: adjusted offensive/defensive efficiency,barthag, projected record, SOS, wins above bubble, adjusted tempo ({year}_team_results.csv). - **
torvik_team_factors()** — team four factors and shooting splits: eFG%, TOV%, OREB%/DREB%, FT rate, 2P/3P/FT splits and assist rates, each with its national rank ({year}_fffinal.csv). - **
torvik_game_schedule()** — full game-by-game schedule and results with pre-game predictions and post-game quality metrics ({year}_super_sked.json). - **
torvik_ncaa_results()** — historical NCAA tournament performance by team, coach, conference or seed, including PASE / PAKE and round-by-round counts (cgi-bin/ncaat.cgi). - **
torvik_player_stats()** — every player's advanced season stat line: offensive rating, usage, shooting splits, rebounding/assist/turnover rates, box plus/minus and per-game box averages (getadvstats.php). - **
torvik_game_stats()** — per-team-game stats: adjusted and raw offensive/defensive efficiency, four factors on both ends, tempo, result and pre-game win probability (getgamestats.php).
Requests route through hoopR's shared .retry_request() layer with a browser
User-Agent; every wrapper returns a hoopR_data tibble with a 3-column
@return table and reports errors via the standard cli reporters. (Note: the
cbbdata/api.cbbdata.com service that previously brokered Torvik data is
defunct, so these wrap barttorvik.com directly.)
**Basketball-Reference (bref_*)**
New bref_*() function family scraping publicly available NBA data from
Basketball-Reference — a source hoopR
previously did not cover at all (no account or API key required):
- **
bref_players_stats()** — league-wide player season stats; pick the table withtable = "per_game"/"totals"/"advanced"/"per_minute"/"per_poss". - **
bref_teams_stats()** — team season stats (per_game,totals,per_poss,advanced,opponent). - **
bref_standings()** — end-of-season conference standings with SRS and a playoff flag. - **
bref_draft()** — draft results paired with each pick's career totals and advanced metrics. - **
bref_awards()** — end-of-season award voting (MVP, ROY, DPOY, SMOY, MIP, Clutch POY, COY) in one tidy tibble. - **
bref_team_roster()** — a team's season roster. - **
bref_player_game_log()** — a player's game-by-game log for a season (by Basketball-Reference player-id slug, e.g.jokicni01). - **
bref_player_bios()** — the player index for a starting letter (career span, position, height/weight, birth date, college) plus each player's Basketball-Reference id slug — a ready-made player **dictionary**. - **
bref_injuries()** — the current Basketball-Reference NBA injury report.
Two Sports-Reference quirks are handled centrally: secondary tables hidden in
HTML comments are un-commented, and columns are read from each cell's
data-stat attribute (so the multi-row "over-headers" don't mangle column
names). Routes through hoopR's shared .retry_request() with a browser
User-Agent. **Basketball-Reference rate-limits aggressive scraping (~20
requests/minute)** — space repeated calls with Sys.sleep(). Tests are gated
behind BREF_TESTS=1. No new dependencies (rvest already in Imports).
**Salary & mock-draft sources (Spotrac / HoopsHype / NBADraft.net)**
New wrappers for third-party NBA salary and mock-draft sites, all public HTML,
no key required:
- **
spotrac_team_cap()** — team salary-cap allocations, cap space, active players and average age from Spotrac. - **
hoopshype_salaries()** — the **full league's** player salaries (one row per player-season, current + future contract years) from HoopsHype. HoopsHype is now a Next.js app whose single salaries page paginates client-side, but each team page embeds that team's complete roster in its__NEXT_DATA__payload — so this iterates the 30 team pages and stitches them together (~600 players) via a team-by-team approach. - **
nbadraft_mock_draft()** — the current consensus mock draft (both rounds) from NBADraft.net.
**Basketball Insiders** was evaluated but **not** wrapped: its old salary-widget
backend (hw-files.com) is offline, and the surviving page only exposes a
team-cap summary redundant with spotrac_team_cap(). For league-wide player
salaries, espn_nba_player_contracts() remains the most complete source.
**RealGM (realgm_*) — Cloudflare-challenge bypass via headless Chrome**
RealGM sits behind a Cloudflare JavaScript
challenge (cf-mitigated: challenge) that returns **HTTP 403** to every
libcurl-based client (httr2, httr, rvest) regardless of headers —
Cloudflare fingerprints the TLS handshake (JA3) *and* demands a JavaScript
proof-of-work to mint the cf_clearance cookie. An earlier source audit
recorded RealGM as **dead** on that basis. It is **not** dead — it is reachable
with a real browser engine, and 17 realgm_*() wrappers now cover the NBA
endpoint surface:
*Players & personnel*
- **
realgm_players()** — active NBA player index (position, ht/wt, age, current team, years of service, pre-draft team / international club, nationality). - **
realgm_players_abroad()** — NBA-affiliated players on international rosters, with NBA-rights status (a view no first-party feed provides). - **
realgm_future_free_agents()** — projected free-agent classes with Bird / veteran status, production, and the player's listed **agent**. - **
realgm_coaches()** / **realgm_gms()** — current head coaches / general managers with tenure and nationality.
*Standings, teams & stats*
- **
realgm_standings()** — both conferences with record, streak, splits. - **
realgm_teams()** — team index with division and conference. - **
realgm_player_stats(season, stat_type, season_type)** — qualified-player leaderboards (Averages / Totals / Per-X / Advanced / Misc, across Regular Season / Playoffs / Preseason / Summer League). - **
realgm_team_stats(season, stat_type, season_type)** — team statistics. - **
realgm_individual_seasons()** / **realgm_individual_games()** — all-time best individual season / single-game leaderboards.
*Draft & salary*
- **
realgm_draft(year)** — past-draft results (rounds 1–2 + undrafted), with pre-draft team and nationality. - **
realgm_draft_prospects()** — current draft-prospect statistics. - **
realgm_early_entry()** — early-entrant / withdrawal list. - **
realgm_salary_cap()** — salary-cap history & projections (cap, tax, aprons, exceptions). - **
realgm_rookie_scale()** — rookie-scale contract amounts by pick.
*Transactions*
- **
realgm_transactions()** — the league transactions log (RealGM publishes it as a dated narrative, not a table, so this parses the page DOM into one row per transaction with a realDate).
Self-describing returns carry their query parameters back as columns
(realgm_player_stats()/realgm_team_stats() echo season/stat_type/
season_type; realgm_draft() echoes draft_year and a round label). Every
wrapper drives headless Chrome through the optional
chromote package (Chrome solves the
challenge natively in ~2 seconds). chromote + Google Chrome are therefore a
**Suggests-level** requirement for the realgm_* family only; every other hoopR
source still works with the standard HTTP stack.
**NBA injury reports (rotowire_injuries() / bref_injuries())**
RotoWorld (rotoworld.com) was a long-standing NBA injuries source, but NBC has
since shut it down (it now 301-redirects to nbcsports.com/fantasy; the injuries
tool is gone). Two live replacements:
- **
rotowire_injuries()** — the current NBA injury report from RotoWire (a separate, live company). RotoWire renders the grid client-side from a JSON table endpoint, so this reads that JSON directly (player, team, position, injury, status, RotoWire player URL). The projected return date is subscriber-only and comes back asNA. - **
bref_injuries()** — a second source, the Basketball-Reference injury report (see above).
**Basketball analytics utilities (nba_*, no network)**
A set of pure, vectorized basketball-math helpers — standard efficiency /
rating / four-factor calculators. All return NA (not Inf/NaN) on a zero
denominator and are league-agnostic (NBA / WNBA / college box scores):
- Shooting:
nba_true_shooting_pct(),nba_effective_fg_pct(),nba_ft_rate(). - Rating / pace:
nba_possessions(),nba_pace(),nba_offensive_rating(),nba_defensive_rating(),nba_net_rating(). - Player rate stats:
nba_game_score()(Hollinger),nba_usage_rate(),nba_assist_pct(),nba_assist_to_turnover(),nba_turnover_pct(),nba_oreb_pct(), andnba_four_factors()(a tidy four-factors tibble). - Scaling / enrichment:
nba_per_minutes()(per-36 by default),nba_per_possessions()(per-100), andnba_add_advanced_metrics(), which detects the standard box-score columns present in a data frame and appends the advanced metrics it can compute.
**NBA player / team dictionaries & media (nba_*)**
- **
nba_player_dict()** / **nba_team_dict()** — tidy player and team dictionaries (ids, names, teams, conference/division) for joining ids to names and fetching media, with headshot / logo URLs attached. - **
nba_player_headshot_url()** / **nba_team_logo_url()** — vectorized builders for the official NBA CDN headshot and logo URLs.
**NBA result-set helpers (nba_bind_sets() / nba_join_sets() / nba_nest_sets())**
hoopR's NBA Stats wrappers return the endpoint's resultSets verbatim as a
*named list of tibbles* (structure-faithful, lossless). These three pure helpers
reduce that list to a single tibble on demand — making explicit, and composable,
the three common result-set reductions:
- **
nba_bind_sets(tag_column = )** — row-bind the sets into one long tibble, tagging each row with its origin (tactic **B**); columns absent from a set fill withNA. For sets that share a schema, or to stack with a tag. - **
nba_join_sets(join_key = )** — successively left-join the sets into one wide tibble on a shared key (tactic **C**). For different facets of one entity (e.g.PlayerStats+TeamStatsonGAME_ID). - **
nba_nest_sets(keep_cols = , nest_col = )** — keep the key column(s) wide and nest every other column into a list-column, preserving the set origin (tactic **D**). For heterogeneous sets that can't be bound or joined (e.g. a player profile's season totals / career totals / awards).
All three take a named list of tibbles (an nba_*() return) and always return a
tibble. The default hoopR return (the list itself) is the "
The NEWS section is longer than shown here.
From NEWS.md in the release
Install
Health
- OK13 OK2026-08-05
- NOTE12 OK, 1 NOTE2026-08-01
- OK13 OK2026-06-09
- ERROR12 OK, 1 ERROR2026-06-08
- OK14 OK2026-03-10
Documentation
- Help pages
- 338 (95 internal)includes a package overview page
- Examples that run
- 11%21 run in a plain check · 149 only when donttest examples are enabled (R CMD check --as-cran) · 17 never run
- Exported functions with examples
- 82%
- Documented parameters
- 92%
- Return-value docs
- 98%
- Help pages citing references
- 0%
Downloads
Repository
- PRs merged (all time)
- 96%
- Median days to close, 50 most recently updated closed issues
- 648
- Median days to close, 50 most recently updated closed PRs
- 0
Stars over time
Forks over time
Releases over time
Issues over time
PRs over time
Commits over time
16 development-tooling and community-health practices detected across 7 families in the upstream repository
Checks run against github.com/sportsdataverse/hoopr on 2026-10-11.
The R CMD check workflow runs on Linux, macOS and Windows
GitHub Pages site last deployed 2026-10-11 · The repository has a site deploy workflow
pkgdown site last built 2026-10-11
Show all practicesHide 3 practices
This repository shows signs of AI coding tools.
- Claude Codefirst seen 2026-03-16Seen in the repository: CLAUDE.mdNamed in .Rbuildignore: .claude, CLAUDE.mdNamed in .gitignore: .claude
- GitHub Copilotfirst seen 2026-03-16Seen in the repository: .github/copilot-instructions.md
Dependencies
Installing hoopR adds 46 packages (27 with compiled code, 38 MB of source tarballs). Heaviest: stringi 11 MB, data.table 5.7 MB, glmnet 2.7 MB.
Code & Tests
Datasets
People & History
Pick two releases to compare their code metrics.
- 3.1.0Latest2026-08-25 · current release · diff ↗ ·
added 365 exports
bref_awards, bref_draft, bref_injuries, bref_player_bios, bref_player_game_log, bref_players_stats, bref_standings, bref_team_roster, bref_teams_stats, cbbd_conferences, cbbd_conferences_history, cbbd_draft_picks, cbbd_draft_positions, cbbd_draft_teams, cbbd_games, cbbd_games_media, cbbd_games_players, cbbd_games_teams, cbbd_key, cbbd_lines, cbbd_lines_providers, cbbd_lineups_game, cbbd_lineups_team, cbbd_play_types, cbbd_plays_date, cbbd_plays_game, cbbd_plays_player, cbbd_plays_team, cbbd_plays_tournament, cbbd_rankings and 335 more - RR 4.6.0 released · 2026-04-24
- 3.0.02026-03-24 · diff ↗ ·
added 13 exports
espn_mbb_team_current_roster, espn_nba_team_current_roster, nba_boxscoresummaryv3, nba_commonteamyears, nba_dunkscoreleaders, nba_gravityleaders, nba_iststandings, nba_playbyplayv3, nba_scheduleleaguev2int, nba_teamandplayersvsplayers, nba_videoeventsasset, nbagl_live_boxscore, nbagl_live_pbp - RR 4.5.0 released · 2025-04-11
- RR 4.4.0 released · 2024-04-24
- 2.1.02023-11-26 · diff ↗ ·
added 31 exports
espn_mbb_game_rosters, espn_mbb_player_stats, espn_nba_game_rosters, espn_nba_player_stats, helper_espn_mbb_pbp, helper_espn_mbb_player_box, helper_espn_mbb_team_box, helper_espn_nba_pbp, helper_espn_nba_player_box, helper_espn_nba_team_box, nba_boxscoreadvancedv3, nba_boxscoredefensivev2, nba_boxscorefourfactorsv3, nba_boxscorehustlev2, nba_boxscorematchupsv3, nba_boxscoremiscv3, nba_boxscoreplayertrackv3, nba_boxscorescoringv3, nba_boxscoretraditionalv3, nba_boxscoreusagev3, nba_franchiseleaderswrank, nba_infographicfanduelplayer, nba_live_boxscore, nba_live_pbp, nba_scoreboardv3, nba_shotchartlineupdetail, nba_synergyplaytypes, nba_teams, nba_todays_scoreboard, nba_videodetailsasset and 1 more - RR 4.3.0 released · 2023-04-21
- 1.8.02022-06-18 · diff ↗ ·
added 13 exports
espn_mbb_team_stats, espn_mbb_wp, espn_nba_team_stats, espn_nba_wp, nba_drafthistory, nba_gamerotation, nba_pbps, nba_playerheadshot, nba_playerindex, nbagl_pbp, nbagl_players, nbagl_schedule, nbagl_standings - RR 4.2.0 released · 2022-04-22
- 1.5.02021-11-10
- RR 4.1.0 released · 2021-05-18
Package metadata
- First published
- 2021-11-10
- Total releases
- 5 / 5 yrs
- License
- MIT + file LICENSE OSI
- Minimum R
- ≥ 4.1.0
- Bundled data
- 17 KB / 1 file
- Download size
- 1.0 MB
Cite
Cite this package
Run in R for the authors' preferred citation:
citation("hoopR")This package has no citation file, so citation() returns this entry built from DESCRIPTION.
Cite the R Observatory
For a number measured here: a download total, a coverage figure, an archival date.
From data release v2026-10-18, which the citation names so these numbers can be found later. More on citing and the projects behind them.