Table of Contents generated with DocToc
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_*_crosswalk +
load_nba_*_crosswalk)New convenience functions that link team / schedule / player
identities across 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_*_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_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.
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:
cbbd_games(),
cbbd_games_media(), cbbd_games_teams(),
cbbd_games_players(), cbbd_scoreboard()cbbd_plays_game(),
cbbd_plays_player(), cbbd_plays_team(),
cbbd_plays_date(), cbbd_plays_tournament(),
cbbd_play_types()cbbd_substitutions_game(),
cbbd_substitutions_player(),
cbbd_substitutions_team()cbbd_stats_team_season(),
cbbd_stats_team_leaderboard(),
cbbd_stats_team_shooting_season(),
cbbd_stats_player_season(),
cbbd_stats_player_shooting_season()cbbd_lineups_team(),
cbbd_lineups_game()cbbd_ratings_srs(),
cbbd_ratings_adjusted(),
cbbd_ratings_elo()cbbd_rankings()cbbd_lines(),
cbbd_lines_providers()cbbd_recruiting_players(),
cbbd_recruiting_teams(),
cbbd_recruiting_portal()cbbd_draft_teams(),
cbbd_draft_positions(),
cbbd_draft_picks()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.
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.)
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 with table = "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).
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_*) — Cloudflare-challenge bypass via headless
ChromeRealGM 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 real
Date).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.
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 as NA.bref_injuries() — a second source, the
Basketball-Reference injury report (see above).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):
nba_true_shooting_pct(),
nba_effective_fg_pct(), nba_ft_rate().nba_possessions(),
nba_pace(), nba_offensive_rating(),
nba_defensive_rating(), nba_net_rating().nba_game_score() (Hollinger),
nba_usage_rate(), nba_assist_pct(),
nba_assist_to_turnover(), nba_turnover_pct(),
nba_oreb_pct(), and nba_four_factors() (a tidy
four-factors tibble).nba_per_minutes() (per-36 by
default), nba_per_possessions() (per-100), and
nba_add_advanced_metrics(), which detects the standard
box-score columns present in a data frame and appends the advanced
metrics it can compute.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_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 with
NA. 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 + TeamStats on
GAME_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 “keep them all” option.
nba_tidy_*())The per-dataset equivalent of the result-set helpers: each fetches a specific multi-result-set endpoint and applies its canonical reduction in one call, so you get the munged tibble directly. All are resilient to the empty / partial sets stats.nba.com occasionally returns.
nba_tidy_franchise_history() —
[nba_franchisehistory()]’s active + defunct sets row-bound into one
franchise timeline, tagged active / defunct
(tactic B).nba_tidy_boxscore(game_id) — a
traditional player box score with each player’s team totals joined on by
GAME_ID + TEAM_ID (team columns suffixed
_team) (tactic C).nba_tidy_player_profile(player_id) —
[nba_playerprofilev2()]’s many PLAYER_ID-keyed tables
(season/career totals, highs, rankings) nested into a .data
list-column, one row per table (tactic D).The 3.1.0 ESPN wrappers are renamed to the shared sportsdataverse
taxonomy used by cfbfastR (and mirrored in wehoop):
event_competitor* → game_team*,
event_competition → game, event_* → game_*,
and athlete_* → player_* (60 functions). These wrappers are
new in this dev cycle and were never on CRAN, so the rename is applied
directly (no deprecation shims). The web-common-v3
/athletes/{id}/stats wrapper becomes
*_player_stats_v3 (kept alongside the core-v2
*_player_stats, a different endpoint).
13 new load_*() loaders bring NBA and MBB dataset
coverage toward parity with the wehoop load_wnba_*() /
load_wbb_*() families, reading the corresponding
espn_nba_* / espn_mens_college_basketball_*
release tags on sportsdataverse-data:
load_nba_standings(),
load_nba_draft(), load_nba_player_stats(),
load_nba_team_stats(), load_nba_rosters(),
load_nba_game_rosters(),
load_nba_officials().load_mbb_rosters(),
load_mbb_player_stats(),
load_mbb_team_stats(), load_mbb_standings(),
load_mbb_game_rosters(),
load_mbb_officials().Player/team season-stats loaders return long-format frames (averages
/ totals / miscellaneous categories). Draft is NBA-only. All accept a
seasons vector (min 2002, draft min 2003) and the same
dbConnection / tablename dots used by the
update_*_db() helpers.
58 new ESPN wrappers added across 8 domains (29 per league × 2
leagues + 4 NBA-only). All built on shared internal helpers in
R/espn_basketball_*_helpers.R so each MBB / NBA pair stays
DRY — one bugfix in the helper propagates to both public wrappers. Same
internal-helpers-plus-thin-shims pattern wehoop uses for its WBB / WNBA
pair.
| Function | Endpoint family | Description |
|---|---|---|
espn_mbb_athlete_info() /
espn_nba_athlete_info() |
site-v2 | Athlete bio / team / position / status / college / draft info. |
espn_mbb_athlete_overview() /
espn_nba_athlete_overview() |
web-common-v3 | Season overview + last-5-games + news + rotowire notes. |
espn_mbb_athlete_stats() /
espn_nba_athlete_stats() |
web-common-v3 | Per-category stats as a named list (averages / totals). |
espn_mbb_athlete_gamelog() /
espn_nba_athlete_gamelog() |
web-common-v3 | Game-by-game log. |
espn_mbb_athlete_splits() /
espn_nba_athlete_splits() |
web-common-v3 | Long-format home / away / opponent splits. |
espn_mbb_athlete_eventlog() /
espn_nba_athlete_eventlog() |
core-v2 | Per-event log. statistics.$ref URLs returned as
statistics_ref character column (not auto-resolved). |
espn_mbb_athlete_awards() /
espn_nba_athlete_awards() |
core-v2 | Awards (sparse / often empty); empty payload returns a canonical-shape empty tibble. |
espn_mbb_athlete_statisticslog() /
espn_nba_athlete_statisticslog() |
core-v2 | Per-season statistics log. |
| Function | Description |
|---|---|
espn_mbb_team() / espn_nba_team() |
Single-team info as a named list (Info,
Record, NextEvent,
StandingSummary, Coaches). |
espn_mbb_team_roster() /
espn_nba_team_roster() |
Roster (one row per athlete with position, height, weight, headshot). |
espn_mbb_team_schedule() /
espn_nba_team_schedule() |
Schedule (one row per event with opponent, venue, broadcast, result). |
espn_mbb_team_leaders() /
espn_nba_team_leaders() |
Statistical leaders in long format per category-rank-athlete. |
espn_mbb_team_news() /
espn_nba_team_news() |
Team-scoped news feed. |
| Function | Description |
|---|---|
espn_mbb_event_odds() /
espn_nba_event_odds() |
Game-level odds (one row per provider). |
espn_mbb_event_probabilities() /
espn_nba_event_probabilities() |
Paginated play-level win probabilities (page loop capped at 50
pages; respects limit). |
espn_mbb_event_officials() /
espn_nba_event_officials() |
Per-game officials. |
espn_mbb_event_broadcasts() /
espn_nba_event_broadcasts() |
Broadcast outlets. |
| Function | Description |
|---|---|
espn_mbb_leaders() /
espn_nba_leaders() |
League leaders (web-common-v3
statistics/byathlete). |
espn_mbb_venues() / espn_nba_venues() |
Venue catalog. |
espn_mbb_coaches() /
espn_nba_coaches() |
Coach roster. |
espn_mbb_athletes_index() /
espn_nba_athletes_index() |
Paginated athlete index with progress messages. |
espn_mbb_seasons() /
espn_nba_seasons() |
Season list. |
espn_mbb_season_info() /
espn_nba_season_info() |
Single-season info. |
| Function | Description |
|---|---|
espn_mbb_news() / espn_nba_news() |
League-level news feed (site-v2 /news). |
espn_mbb_calendar() /
espn_nba_calendar() |
Scoreboard calendar blocks (site-v2
/scoreboard?dates={season}). |
| Function | Description |
|---|---|
espn_mbb_injuries() /
espn_nba_injuries() |
League-wide injury feed (site-v2 /injuries). |
espn_mbb_team_injuries() /
espn_nba_team_injuries() |
Team-scoped injury feed (site-v2
/teams/{id}/injuries). |
MBB injury data is typically sparse on ESPN; both variants return an empty tibble (rather than erroring) when no injuries are reported.
| Function | Description |
|---|---|
espn_nba_draft() |
Paginates core-v2 /seasons/{year}/draft (up to 20
pages); flat tibble of picks. |
espn_nba_freeagents() |
Wraps core-v2 /seasons/{year}/freeagents; returns an
empty tibble outside the off-season free-agent window. |
espn_nba_transactions() |
Wraps site-v2
/transactions?season={year}&limit={limit} with
null-safe to_team_id for release transactions. |
espn_nba_conferences() |
NBA-side analog of espn_mbb_conferences(), against the
NBA scoreboard-conferences endpoint. |
22 new wrappers across 9 resource families, surfaced by an internal
$ref-following crawler that mapped the reachable basketball
API surface (21,962 fetches, 1,570 unique templates across all 4
basketball leagues). Each wrapper is a thin shim over a shared
.espn_basketball_*() helper. WNBA + WBB siblings ship in
wehoop’s matching release.
| Function | Description |
|---|---|
espn_nba_team_season_profile() /
espn_mbb_team_season_profile() |
Era-correct team identity in a specific season plus
$ref URLs for deeper resources (record, statistics,
leaders, coaches, etc.). Historical depth back to 1947
(NBA) / 1939 (MBB). |
espn_nba_franchise() /
espn_mbb_franchise() |
Franchise-level metadata. IDs are stable across relocations and rebrands. |
espn_nba_franchises() /
espn_mbb_franchises() |
Index of franchise IDs in the league. |
espn_nba_athlete_contracts() |
Index of contract seasons recorded for an NBA athlete (NBA-only — WNBA athletes return empty). |
espn_nba_athlete_contract() |
Salary, cap-rule flags, Bird status, and trade protections for one (athlete × season). |
espn_nba_season_awards() /
espn_mbb_season_awards() |
Index of award IDs given out in a season. |
espn_nba_award() / espn_mbb_award() |
Award detail with winners (one row per winner; multi-recipient awards like All-NBA return 5 rows). |
espn_nba_futures() /
espn_mbb_futures() |
Per-season futures betting board in long format (one row per market × team × sportsbook). |
espn_nba_tournaments() /
espn_mbb_tournaments() |
Index of league-tracked tournaments. |
espn_nba_tournament() /
espn_mbb_tournament() |
Single tournament metadata + seasons-list $ref. |
espn_nba_tournament_seasons() /
espn_mbb_tournament_seasons() |
Seasons in which a given tournament was held. |
espn_nba_team_record() /
espn_mbb_team_record() |
Long-format record breakdown for one team in one season-type (Overall / Home / Road / vs Conference / etc.). |
espn_nba_coach() / espn_mbb_coach() |
Single-coach biography, current team / college refs, and counts of career-record + per-season coaching entries. |
espn_nba_powerindex() /
espn_mbb_powerindex() |
Per-season Basketball Power Index and related metrics, long format (one row per team × stat). |
10 new wrappers across 5 resource families covering season-level
metadata: season types, the per-(season × season-type) leaderboards, and
(mostly college-only) season rankings. Backed by a shared
R/espn_basketball_season_meta_helpers.R. WNBA + WBB
siblings ship in wehoop’s matching release.
| Function | Description |
|---|---|
espn_nba_season_types() /
espn_mbb_season_types() |
Index of season-type IDs that exist for one season (1 = preseason, 2 = regular, 3 = postseason, 4 = off-season). |
espn_nba_season_type() /
espn_mbb_season_type() |
Single season-type detail (start / end dates, has-groups /
has-standings / has-legs flags, $ref URLs to deeper
resources). |
espn_nba_season_leaders() /
espn_mbb_season_leaders() |
Per-(season × season-type) leaderboards in long format (one row per category × rank). 14–15 categories × 25 leaders ≈ 350 rows. |
espn_nba_season_rankings() /
espn_mbb_season_rankings() |
Index of season-level rankings recorded for a season (NBA / WNBA return zero; MBB / WBB return AP Top 25 + Coaches Poll). |
espn_nba_season_ranking() /
espn_mbb_season_ranking() |
Per-week snapshot index for one ranking source — each row resolves to a per-week ranked-teams endpoint. |
8 new wrappers across 4 resource families covering the week structure
of a season. Backed by a shared
R/espn_basketball_week_helpers.R. WNBA + WBB siblings ship
in wehoop’s matching release.
| Function | Description |
|---|---|
espn_nba_season_weeks() /
espn_mbb_season_weeks() |
Index of weeks within one (season × season-type). Typical: ~20 weeks for regular season. NBA / WNBA also have weeks; rankings only populate for MBB / WBB. |
espn_nba_season_week() /
espn_mbb_season_week() |
Single-week metadata (number, start / end dates, text label,
$ref to the per-week rankings endpoint). |
espn_nba_week_rankings() /
espn_mbb_week_rankings() |
Index of ranking sources for one week (NBA returns zero; MBB returns AP + Coaches). |
espn_nba_week_ranking() /
espn_mbb_week_ranking() |
The ranked teams (typically 25 rows) for one (season-type × week ×
source). Includes current / previous rank, points, first-place votes,
trend, record summary, team $ref. |
8 new wrappers across 4 resource families covering the per-season
group hierarchy (conferences, divisions, and member teams). Backed by a
shared R/espn_basketball_group_helpers.R. WNBA + WBB
siblings ship in wehoop’s matching release.
| Function | Description |
|---|---|
espn_nba_season_groups() /
espn_mbb_season_groups() |
Index of group IDs (conferences / divisions) for one (season × season-type). |
espn_nba_season_group() /
espn_mbb_season_group() |
Single-group metadata (name, abbreviation, midsize / short name,
is_conference flag) plus $ref URLs to parent,
children, member teams, and standings. |
espn_nba_season_group_children() /
espn_mbb_season_group_children() |
Index of child groups (e.g. divisions inside a conference, or conferences inside the NCAA Division I umbrella group). |
espn_nba_season_group_teams() /
espn_mbb_season_group_teams() |
Index of team IDs that belong to the group for that (season × season-type). |
7 new wrappers across 4 resource families covering deeper per-team
and per-coach core-v2 endpoints. Backed by a shared
R/espn_basketball_team_deep_helpers.R. WNBA + WBB siblings
(where applicable) ship in wehoop’s matching release.
| Function | Description |
|---|---|
espn_nba_team_odds_records() /
espn_mbb_team_odds_records() |
Long-format odds-records breakdown (Money Line / ATS / O/U × Overall
/ Home / Road × W/L/Push). Sparse — many (team × season-type)
combinations return empty. Default season_type = 0
(all-types aggregate, where ESPN actually populates). |
espn_nba_team_depthchart() |
NBA-only long-format depth chart (one row per position × rank × athlete). |
espn_nba_team_season_roster() /
espn_mbb_team_season_roster() |
Per-season roster (core-v2
seasons/{y}/teams/{id}/athletes). Distinct from the
existing site-v2 espn_*_team_roster(): era-correct,
available back to the league’s earliest season. |
espn_nba_coach_season() /
espn_mbb_coach_season() |
Single-coach metadata for one (coach × season). Includes name, birth
info, and $refs to person / college / team. Sparse coverage
— many combinations 404. |
5 new wrappers across 3 resource families covering career-level
athlete endpoints and the single-draft-pick lookup. Backed by
R/espn_basketball_athlete_career_helpers.R and
R/espn_basketball_draft_helpers.R.
| Function | Description |
|---|---|
espn_nba_athlete_seasons() /
espn_mbb_athlete_seasons() |
List of seasons an athlete appeared in. |
espn_nba_athlete_career_stats() /
espn_mbb_athlete_career_stats() |
Long-format career stats. Default stat_type = 0L
fetches the standard “All Splits” / regular-season view; pass a vector
like c(0L, 1L, 2L) to bind multiple types (postseason /
career aggregate) via a stat_type_id column. Coverage of
types 1 and 2 is sparse — many athletes only populate type 0. |
espn_nba_draft_pick() |
Single NBA draft-pick detail (defaults to most-recent NBA season, round 1, pick 1). MBB has no draft endpoint, so this wrapper is NBA-only on the hoopR side. |
5 new wrappers across 2 resource families. Extends the athlete and draft endpoint coverage with the remaining per-season core-v2 endpoints.
| Function | Description |
|---|---|
espn_nba_athlete_eventlog_v2() /
espn_mbb_athlete_eventlog_v2() |
Per-season event log from core-v2
(seasons/{y}/athletes/{id}/eventlog). One row per (event ×
team) appearance with played flag + event/competition
$refs. Distinct from the existing
espn_*_athlete_eventlog() which hits the web-common-v3
gamelog endpoint with stats per game. |
espn_nba_draft_rounds() |
Round-level summary for one NBA draft year (one row per round with pick count + completion status). |
espn_nba_draft_athletes() |
Index of every athlete in a given NBA draft year (~102 entries: 60 picks + undrafted invitees). |
espn_nba_draft_status() |
Single-row snapshot of one draft year’s current state. |
8 new wrappers across 4 resource families. Each wraps
events/{eid}/competitions/{cid}/... and is added to both
NBA and MBB shim files (16 new public functions across both leagues per
package = 8 each).
| Function | Description |
|---|---|
espn_nba_event_situation() /
espn_mbb_event_situation() |
Live game situation: timeouts, fouls, fouls-to-give, bonus state,
last-play $ref. Single-row tibble. |
espn_nba_event_predictor() /
espn_mbb_event_predictor() |
Pre-game predictor statistics in long format (one row per team × stat). Stats include matchup quality, predicted score, win pct, team-predicted MoV. Returns empty for events without predictor data. |
espn_nba_event_powerindex() /
espn_mbb_event_powerindex() |
Per-event power-index $ref index. Coverage is sparse —
most events return zero items. |
espn_nba_event_propbets() /
espn_mbb_event_propbets() |
Per-(event × provider) prop-bet markets in long format. One row per (athlete × prop type) with american / decimal / fraction odds + current target line. Auto-paginates. |
5 new resource families under
events/{eid}/competitions/{cid}/competitors/{team_id}/,
each shimmed for NBA and MBB (10 new public functions per package). Pair
the team_id with the event_id from espn_*_schedule() (or
any boxscore.teams[].id).
| Function | Description |
|---|---|
espn_nba_event_competitor_linescores() /
espn_mbb_event_competitor_linescores() |
Per-quarter scoring for one team in one event. One row per period (regulation + overtime). |
espn_nba_event_competitor_leaders() /
espn_mbb_event_competitor_leaders() |
Top performers per team in long format: one row per (category × athlete rank). Categories typically include points, rebounds, assists, and rating. |
espn_nba_event_competitor_roster() /
espn_mbb_event_competitor_roster() |
Game-day roster index for one team. Returns athlete ids + core-v2
$ref URLs for deferred dereferencing. |
espn_nba_event_competitor_statistics() /
espn_mbb_event_competitor_statistics() |
Full team-game statistics in long format (one row per category × stat) with both numeric values and display strings. |
espn_nba_event_competitor_records() /
espn_mbb_event_competitor_records() |
Team records as of the event: overall / home / away / conference / division breakdowns. |
5 new resource families completing index/detail pairs for existing wrappers. NBA-only or 3-league coverage where the underlying ESPN endpoint isn’t symmetric:
| Function | Description |
|---|---|
espn_nba_event_official_detail() /
espn_mbb_event_official_detail() |
Per-official details (name, position, order) for one event.
Note: the URL segment is the crew order
(1-indexed) not the ESPN stable official_id — the wrapper takes
order = to match event_officials()$order. |
espn_nba_team_record_detail() /
espn_mbb_team_record_detail() |
Per-record stat array in long format. Use team_record()
to enumerate record_id values (overall / home / away /
conference / per-opponent). Returns 21 rows × 15 cols for one NBA
record. |
espn_nba_coach_record() /
espn_mbb_coach_record() /
espn_wbb_coach_record() |
Coach career record by type in long format. Types: 0 = Total, 1 = Pre Season, 2 = Regular Season, 3 = Post Season. |
espn_nba_tournament_season() /
espn_mbb_tournament_season() |
Single tournament-year detail (id, displayName, numberOfRounds,
bracketology $ref). |
espn_nba_draft_athlete_detail() |
Rich single-row drafted-player record: height/weight, position, pick
(overall/round/team), athlete $ref. |
3 new resource families across NBA + MBB (5 new exports — season_draft is NBA-only). Surfaces the full team-season stat sheet (with league rank per stat), a quick-lookup wrapper for a single team’s final score in one event, and the draft-year top-level metadata.
| Function | Description |
|---|---|
espn_nba_team_season_statistics() /
espn_mbb_team_season_statistics() |
Full team-season-type stat sheet in long format
(one row per category × stat). Each row carries rank +
rank_display_value for league ranking per stat.
Smoke-tested: 109 rows × 13 cols for one NBA team. |
espn_nba_event_competitor_score() /
espn_mbb_event_competitor_score() |
Single-row final score for one team in one event:
value, display_value, winner
flag, source metadata. |
espn_nba_season_draft() |
Draft-year top-level metadata: year,
number_of_rounds, display_name, plus sub-refs
to athletes/rounds/status. |
4 new resource families covering per-game player stats, starter/DNP metadata, single-play detail, and on-court personnel (8 new public functions per package).
| Function | Description |
|---|---|
espn_nba_event_player_box() /
espn_mbb_event_player_box() |
Per-game box score for one athlete in long format
(one row per category × stat). Same shape as
event_competitor_statistics() but scoped to a single
athlete-in-event. Smoke-tested: 99 rows × 12 cols for one NBA
athlete. |
espn_nba_event_competitor_roster_entry() /
espn_mbb_event_competitor_roster_entry() |
Per-athlete game-day roster row: starter flag,
did_not_play + reason, ejected,
period of entry, for_player_id if a
substitution. |
espn_nba_event_play() /
espn_mbb_event_play() |
Rich single-play detail: sequence, period, clock, type, text,
scoring/shooting flags, score, team $ref, shot
coordinates. |
espn_nba_event_play_personnel() /
espn_mbb_event_play_personnel() |
Players on court at a specific play in long format. Coverage is sparse — many plays return zero rows; wrapper returns a typed empty tibble. |
2 new resource families for the league-specific position dictionary
(4 new public functions). Position ids are not shared
across the basketball family — id 1 resolves to
Point Guard in NBA and Center in MBB. These
wrappers make the dictionary explicit so users can disambiguate position
$ref URLs in athlete records.
| Function | Description |
|---|---|
espn_nba_positions() /
espn_mbb_positions() |
League position dictionary index. One row per position with id +
canonical $ref. |
espn_nba_position() /
espn_mbb_position() |
Single-position detail: id, name, displayName, abbreviation, leaf
flag, parent $ref. |
| Function | Fix |
|---|---|
nba_schedule() |
Migrated off the retired
stats.nba.com/stats/scheduleleaguev2 endpoint (returns
Connection was reset across multiple client environments;
issues #184 and #187) to the public CDN at
cdn.nba.com/static/json/staticData/scheduleLeagueV2.json.
Same leagueSchedule.gameDates[].games[] payload, no
authentication or special headers, stays current with the live season.
G-League schedules now come from the _2-suffixed variant on
the same CDN. For historical seasons (CDN only serves the current
season) the function emits a message() directing users at
load_nba_schedule(seasons = ...). Also initializes
games <- NULL before tryCatch (issue #184).
Verified 2026-05-16: returns 1,398 NBA games × 52 cols for 2025-26. |
nba_leaguegamelog() |
Reordered query-string parameter ordering to put
LeagueID first. As of 2026 the NBA Stats API rejects the
alphabetical ordering
(Counter, DateFrom, DateTo, Direction, LeagueID, ...) with
a Cloudflare HTML error page; LeagueID-first matches the
nba.com client and parses successfully. Verified 2026-05-16: returns
2,460 NBA rows with SEASON_ID=22025. Parallel fix to the
WNBA equivalent in wehoop. |
ncaa_mbb_NET_rankings() |
Hardened against NCAA.com column drift. The function now uses
dplyr::rename(dplyr::any_of(...)) so renamed / added
columns (e.g. new Quad 1..4 headers) no longer break the
documented schema; existing consumers keep working and new columns ride
along untouched. |
| ESPN wrappers | Moved .retry_request() and check_status()
inside tryCatch so transient HTTP errors surface
as cli_alert_danger() + empty fallback rather than escaping
the function. Affects every espn_nba_* /
espn_mbb_* wrapper. |
ncaa_mbb_teams() |
No longer returns NA ids. stats.ncaa.org
migrated team links from the legacy
/team/{team_id}/{season_id} pair to a single modern
/teams/{season_team_id} resource, so the previous
str_extract("(\\d+)/(\\d+)") matched nothing. The function
now extracts ids from whichever url shape is present (legacy rows
populate team_id/season_id; modern rows
populate the new season_team_id column), so the id columns
are never all-NA when the site flips formats. |
Every @return markdown table across the 39 R source
files is upgraded from two columns (col_name | types) to
three columns (col_name | types | description).
6,039 total table rows touched; every result set on
every function now ships a per-column description in
?<function> help, the pkgdown reference, and the
rendered man pages.
Coverage — frequency-weighted, what ?fn
readers actually see — 58.4% of the 6,039 @return table rows now carry a hand-quality
description (curated + ESPN-API + mined). The remaining 41.6%
are heuristic-fallback rows; the heuristic generator’s snake_case
expansion + suffix rules cover most of those acceptably, and the long
tail is dominated by single-occurrence columns from low-traffic NBA
Stats endpoints.
Description sources (precedence order, first match wins):
tools/docs/column_descriptions_curated.csv — 619
hand-authored entries covering high-traffic columns and basketball /
ESPN domain conventions.tools/docs/column_descriptions_api.csv — 188
ESPN-authored descriptions mined live from 14 endpoints per league
across both nba and mens-college-basketball,
covering 9 endpoint families: core-v2 athlete statistics (per-season,
post-season, career), core-v2 team statistics, core-v2 statisticslog,
core-v2 leaders, web-v3 athlete stats / splits / gamelog / overview, and
web-v3 statistics/byathlete leaderboards. Three response shapes are
recognized: nested categories with stats objects, parallel arrays under
categories, and top-level parallel-array shapes (splits / gamelog).\item{...}{...} lines from existing
\describe{} blocks.*_id, *_pct, *_made,
*_attempted, *_per_36, etc.) with
basketball-friendly noun substitution.New tooling under tools/docs/
(.Rbuildignore’d via the existing ^tools$
rule):
| File | Purpose |
|---|---|
build_column_descriptions.R |
One-shot dictionary builder. |
column_descriptions_curated.csv |
Hand-edit surface; overrides API / mined / heuristic outputs. |
column_descriptions_api.csv |
ESPN-API-mined descriptions, regenerated by
mine_api_descriptions.R. |
column_descriptions.csv |
Generated dictionary (1,956 rows; 619 curated, 168 ESPN-API, 5 mined, 0 parameter-overlap, 1,164 heuristic). |
mine_api_descriptions.R |
Driver that probes the ESPN endpoints which self-document their stat columns. |
audit_column_descriptions.R |
Coverage / leverage diagnostic. |
markdown_man_table_helper.R |
Programmatic helpers (load_column_descriptions(),
make_return_table_md(), roxygenize_return(),
augment_return_tables_in_file(),
augment_all_r_files(),
mine_espn_api_descriptions(url)). |
espn_endpoints_catalog.md |
Basketball-scoped ESPN endpoint reference used to scope the miner. |
The sweep is idempotent and offline (no API calls needed for the
augmentation itself; existing |col_name|types| tables in
each @return block are the parse input).
When the package migrated from httr to
httr2 in 3.0.0, the legacy httr::use_proxy()
plumbing was dropped and request_with_proxy() quietly
stopped honoring proxies (its ... was preserved purely for
source compatibility). Both request_with_proxy() and the
lower-level .retry_request() now accept a
proxy = argument:
proxy = NULL (default) — libcurl reads
http_proxy / https_proxy /
no_proxy env vars automatically.proxy = "http://host:port" — string form, forwarded to
httr2::req_proxy(url = ...).proxy = list(url=, port=, username=, password=, auth=)
— named list spread into httr2::req_proxy() for
authenticated proxies.Resolution order in .retry_request(): explicit
proxy = arg → getOption("hoopR.proxy") →
libcurl env vars. The ... thread works for NBA Stats
wrappers (which forward into request_with_proxy()); ESPN /
KenPom / NBA G-League wrappers call .retry_request()
directly without ..., so use
options(hoopR.proxy = ...) at the top of the session to
cover those without per-function plumbing.
| Helper | Role |
|---|---|
.report_api_error(e, hint, args) |
Standardized tryCatch error handler — emits a
cli_alert_danger() with hint text plus the captured arg
list, then returns an empty fallback. |
.report_api_warning(w, args) |
Companion warning handler. |
.interp_braces() |
Internal helper for safely interpolating {var} syntax
in cli alerts when the variable might contain braces of its own. |
.capture_args() |
Helper used at the top of arg-less wrappers (i.e. those whose only
formal is ...) so the error/warning reporters still see the
call args. Equivalent to
mget(setdiff(names(formals()), "...")) for wrappers with
formals. |
Every tryCatch(expr = ...) block in ESPN, NBA Stats, and
KenPom wrappers now uses these helpers instead of hand-rolled
cli::cli_alert_danger("{Sys.time()}: ...") strings.
Behavior is the same; the message includes the captured args, which
makes failed-call debugging much faster.
glue from Imports; demoted to
Suggests (retained only for downstream package-level
references).glue::glue(...) call-sites with
sprintf() / paste0() / base R in URL builders,
pad_id(), pad_time(), and cli
alert strings.glue::glue_sql() with parameterized
DBI::dbExecute() / DBI::dbGetQuery() calls in
load_* family functions.tools/ patch scripts
(patch_df_list_init.R,
patch_return_var_init.R,
flip_expect_equal_cols.R, inject_skip_guard.R,
inject_skip_helpers.R, sweep_error_handlers.R,
find_parse_errors.R) for future audit / sweep work.tools/run_doctoc.R — a no-deps R replacement for
the npm doctoc CLI, used to regenerate the NEWS.md /
CONTRIBUTING.md TOCs. Run with
Rscript tools/run_doctoc.R --maxlevel 2 NEWS.md CONTRIBUTING.md.tools/ scripts: return-value init guards on edge-case
wrappers, subset-direction column assertions, skip-on-empty guards where
wrappers can legitimately return empty.36 further bulk-data loaders, following the established
load_*() shape:
sportsdataverse-py engine (hoopR ships loaders only):
load_ncaa_mbb_pbp(), _shots(),
_lineups(), _matchup_stints(),
_possessions(), _rapm() (league-wide
regularized adjusted plus-minus), _rapm_within_team(),
_player_box(), _team_box(),
_rosters(), _team_rosters(),
_schedule(), and _team_ids().load_nba_shots() and load_mbb_shots() for
ESPN shot events (20-column schema verified against real downloaded
assets). load_mbb_shots() documents and enforces the
2004/2005 gap seasons (no shot-coordinate assets were published for
those two seasons).load_nba_player_impact()
(RAPM/SPM/BPM/DARKO), load_mbb_ratings() (KenPom-style
adjusted efficiency), and load_mbb_player_value()
(box-BPM), reading the nba_player_impact /
mbb_ratings / mbb_player_value release tags.
The latter two are parquet-only, so parquet_from_url() is
added to utils.R and arrow moves into
Suggests.nba_stats release-dataset family
mirroring the wnba_stats_* loaders in wehoop:
17 tag loaders (load_nba_stats_coaches(),
_draft(), _game_lineups(),
_game_rosters(), _lineups(),
_officials(), _pbp(),
_player_boxscores(), _player_game_logs(),
_player_season_stats(), _possessions(),
_rosters(), _schedule(),
_shots(), _standings(),
_team_boxscores(), _team_season_stats()) plus
load_nba_stats_leaguedash() (a 36-table cube),
update_nba_stats_db(), and
most_recent_nba_stats_season(). Seasons are keyed
on the START year (e.g. 2024 = the 2024-25
season), unlike the ESPN-backed load_nba_*() family which
keys on the season’s end year — documented on each function.All were verified live against the published release assets, with returns documentation derived from the real files.
... is now genuinely forwarded to
DBI::dbWriteTable() across 23 loader call sites, and the
dead dots <- rlang::dots_list(...) capture that never
fed anywhere is removed.dbConnection/tablename write without
performing it now perform it: load_nba_team_box(),
load_nba_standings(), load_nba_game_rosters(),
load_nba_officials(), load_nba_draft(),
load_nba_player_stats(),
load_nba_team_stats(), load_nba_rosters(),
load_nba_player_core(), load_mbb_rosters(),
load_mbb_player_stats(),
load_mbb_team_stats(), load_mbb_standings(),
load_mbb_game_rosters(), load_mbb_officials(),
load_mbb_player_core().hoopR_data class vector
(make_hoopR_data() and every load_nba_*() /
load_mbb_*() / crosswalk loader): "data.table"
had been mixed into the class vector alongside "tbl_df"
without the internal state data.table needs, so
tail()/head() dispatched
data.table:::tail.data.table(), whose row-filter
re-dispatched to tibble:::[.tbl_df() (column semantics, not
row semantics) and threw
Error in x[i]: Can't subset columns past the end.
tail()/head()/
print()/dplyr::filter() now work correctly on
loader results. Fixes #88.A residential-IP live re-probe (2026-08-24) of the
nba_stats family’s mis-flagged/untested/dead-exported
endpoints, backed by real probes rather than the endpoint catalog’s
capture flags alone:
nba_scoreboardv2()
(lifecycle::deprecate_stop() removed — confirmed live with
real rows).nba_videoeventsasset() — HTTP 200 with zero rows across
multiple game/event IDs;
lifecycle::deprecate_warn(when = "3.1.0") (call still
proceeds).nba_boxscoreadvancedv2() is dead for NBA
(LeagueID '00') but live for WNBA ('10') and
G-League ('20') — gains a @details note
instead of a deprecation.@details on every
already-deprecated endpoint that was re-probed and kept deprecated
(nba_boxscorehustlev2(), nba_homepageleaders()
/ nba_homepagev2() / nba_leaderstiles(),
nba_boxscoreplayertrackv2(), nba_scoreboard(),
nba_teamhistoricalleaders(),
nba_videodetails(),
nba_winprobabilitypbp()).nba_scoreboard() /
nba_scoreboardv2() point real-time users at
nba_todays_scoreboard(); nba_homepageleaders()
notes stat_category = "Defense" was never supported
upstream; a shared ?hoopR note covers
stats.nba.com / stats.wnba.com blocking
datacenter/cloud IPs and the options(hoopR.proxy = ...)
escape hatch.LeagueID-first parameter-ordering fix applied to
nba_leaguegamelog() in 3.1.0 (see Bug fixes above) is now
applied mechanically to every other nba_stats_*.R wrapper
that sends a LeagueID param — 78 params-list sites across
15 files. No signature or behavior changes.espn_mbb_scoreboard() unioned four ESPN group IDs (56,
55, 50, 100) without deduplicating, so a game tagged under more than one
group was double-counted (e.g. 18 rows for a 10-game slate). Fixed with
dplyr::distinct(game_id, .keep_all = TRUE). Fixes
#160.espn_mbb_betting() / espn_nba_betting():
ESPN’s Site v2 summary payload now frequently ships an
empty pickcenter array. Both now cascade to the Core v2
event odds endpoint and map its columns onto the documented
pickcenter shape when the summary is empty. Fixes #136,
#153, #173.espn_mbb_standings() switches from ESPN’s flat
level=1 list to level=3 (conference-grouped),
which includes D1 newcomers the flat list drops, and gains a
conference column. espn_mbb_teams() backfills
the same conference-crawl information for team ids its own flat
teams?limit=1000 fetch independently drops. Fixes #144 (all
366 teams now returned).espn_mbb_scoreboard() /
espn_nba_scoreboard(): max_year was character,
so max_year + 1 threw for out-of-range seasons — cast to
integer. espn_mbb_scoreboard() also passed a bare season
year straight through to ESPN’s dates= param, which ESPN
treats as calendar-year-only (Jan 1 onward), silently dropping the
season’s November/December games; for a season-year input it now
additionally queries the prior calendar year and backfills the
high-volume window (which otherwise hits ESPN’s limit=1000
cap before reaching Nov/Dec) with one request per day, filtered to the
season ESPN itself assigns each game and deduplicated. Fixes #150.kp_team_depth_chart(): KenPom removed the
#dc-table table from team.php — the page now
ships an empty <div id="depth-chart"> rendered
client-side from a const players = [...] JSON array
embedded in an inline <script> tag. The parser is
repointed at that embedded JSON. The new source reports each rostered
player’s percentage of minutes at every position rather than a single
starter/backup per slot, so the return shape changed from one
wide row per team to one row per player with
pct_pg/pct_sg/pct_sf/pct_pf/pct_c
columns. Fixes #152.skip_on_cran() to every test_that()
block (466 blocks).cph (copyright holder) role to
Saiem Gilani in Authors@R (CRAN strict
requirement caught between releases).usethis::use_tidy_description() — field order, alphabetized
Imports/Suggests, reflowed long lines..gitignore anchored from bare docs to
/docs so only the repo-root pkgdown output is ignored (the
bare pattern was also matching tools/docs/).| Function / change | Description |
|---|---|
nba_playbyplayv3() |
Dedicated wrapper for the NBA Stats PlayByPlayV3 endpoint. |
nba_pbp() default flip |
Now defaults to version = "v3" (was "v2").
Pass version = "v2" for the previous behavior. |
nba_pbps() default flip |
Same default flip applies. |
nba_pbp() p parameter |
Now optional (default NULL) — previously required even
when not using progress tracking. |
Internal V3→V2 compatibility pipeline backs nba_pbp() so
callers keep V2-compatible columns while gaining V3-only columns
(x_legacy, y_legacy,
shot_distance, shot_result,
is_field_goal, points_total,
shot_value):
| Helper (internal) | Role |
|---|---|
.v3_to_v2_format() |
Converts V3 play-by-play data to V2-compatible column format with mapped event types and player resolution. |
.build_player_roster() |
Retrieves player roster from
nba_boxscoretraditionalv3() for name-to-ID resolution
during V3-to-V2 conversion. |
.players_on_court_v3() |
Rewritten — uses nba_gamerotation() stint data with
interval mapping for robust on-court determination (replaces the
previous substitution-parsing approach). |
Removed stringr::str_match import from NAMESPACE — V3
clock parsing now uses base R regex functions.
| Function | Description |
|---|---|
nba_boxscoresummaryv3() |
Returns a named list of 9 data frames: GameSummary,
GameInfo, ArenaInfo, Officials,
LineScore, InactivePlayers,
LastFiveMeetings, OtherStats,
AvailableVideo. |
| Function | Description |
|---|---|
nba_commonteamyears() |
Team IDs with their active year ranges. |
nba_dunkscoreleaders() |
Dunk tracking data with biomechanics, scores, and style metrics. |
nba_gravityleaders() |
Gravity scores — how much defensive attention each player draws. |
nba_iststandings() |
In-Season Tournament (NBA Cup) standings. |
nba_scheduleleaguev2int() |
International schedule data with broadcaster information. |
nba_teamandplayersvsplayers() |
Team and player lineup comparison stats (5 datasets). |
nba_videoeventsasset() |
Video event asset data for a given game event. |
| Function | Description |
|---|---|
espn_nba_team_current_roster() |
Current NBA team roster from ESPN. |
espn_mbb_team_current_roster() |
Current MBB team roster from ESPN. |
nbagl_live_pbp() |
Live G-League play-by-play. |
nbagl_live_boxscore() |
Live G-League box score. |
| Function | Fix |
|---|---|
nba_iststandings() |
Nested games column now properly flattened. |
nba_dunkscoreleaders() |
HTTP 400 error caused by empty-string parameters now resolved. |
nbagl_pbp() |
Avoids on-court enrichment dependency failures for G-League game IDs by using the stable core play-by-play path. |
kp_box() |
Referee link extraction updated — CSS selectors now match current
KenPom HTML structure (div.refline with href-based
filtering). |
kp_team_history() |
CSS selector updated to table#player-table; team name
assignment now uses the display name instead of the URL slug. |
kp_kpoy() example |
Year bumped from 2021 to 2026 for current-season relevance. |
Return-value initialization sweep. Fixed
df_list not initialized before tryCatch in
147 NBA Stats API wrapper functions, preventing crashes
on API errors. Same pattern applied to: * nba_data_pbp()
(plays_df init). * nba_playbyplayv3() and
nba_pbp() (data init). * NBAGL wrappers
(return-object init across error paths).
Other fixes: * helper-skip.R test guard
functions now use string comparison (!= "1") instead of
numeric comparison (== 0). * V3-style data.frame parsing
fixed for leader/standings endpoints. * %||% import added
for R < 4.4.0 compatibility. * teams_links dataset
updated with 2026 season team data.
Calling any of these now errors with a structured
lifecycleDeprecatedError that names a replacement. All
deprecations were prompted by unstable / partial / empty endpoint
responses observed in production.
| Deprecated function | Replacement | Reason |
|---|---|---|
nba_boxscorefourfactorsv2() |
nba_boxscorefourfactorsv3() |
Unstable/partial V2 responses |
nba_boxscoremiscv2() |
nba_boxscoremiscv3() |
Unstable/partial V2 responses |
nba_boxscorescoringv2() |
nba_boxscorescoringv3() |
Unstable/partial V2 responses |
nba_boxscoreusagev2() |
nba_boxscoreusagev3() |
Unstable/partial V2 responses |
nba_boxscoreplayertrackv2() |
nba_boxscoreplayertrackv3() |
Unstable/partial V2 responses |
nba_boxscorehustlev2() |
nba_hustlestatsboxscore() |
Unstable/partial V2 responses |
nba_homepageleaders() |
nba_leagueleaders() |
Unstable/empty responses |
nba_homepagev2() |
nba_leagueleaders() |
Unstable/empty responses |
nba_leaderstiles() |
nba_leagueleaders() |
Unstable/empty responses |
nba_teamgamestreakfinder() |
nba_teamgamelogs() |
Unstable/empty responses |
nba_teamhistoricalleaders() |
nba_franchiseleaders() |
Unstable/empty responses |
nba_videodetails() |
nba_videodetailsasset() |
Unstable/empty responses |
nba_winprobabilitypbp() |
nba_playbyplayv3() |
Unstable/empty responses |
nba_playercareerbycollege() |
nba_playercareerbycollegerollup() /
nba_leaguedashplayerbiostats() |
Unstable/empty responses |
nba_playernextngames() |
nba_playerprofilev2() |
Unstable/empty responses |
nba_scoreboard() |
nba_scoreboardv3() |
Unstable/empty responses |
nba_scoreboardv2() |
nba_scoreboardv3() |
Unstable/partial responses |
Breaking change: httr is replaced with
httr2 as the HTTP backend for every API call across the
package, and httr is removed from Imports.
Migration map:
| Aspect | Before (2.1.0 and earlier) | After (3.0.0) |
|---|---|---|
| HTTP client backend | httr |
httr2 |
httr package availability |
Auto-imported with hoopR |
Removed from Imports — library(httr)
yourself if your downstream code still needs it |
request_with_proxy() body |
rvest::session() + httr::config()
arguments |
httr2::request() + retry pipeline |
| All ESPN / NBA Stats / NBA G-League / NCAA / KenPom HTTP calls | Mixed direct backend calls | Routed through shared internal helpers
(.retry_request(), .resp_text()) backed by
httr2 |
check_status() internal |
httr::status_code() |
httr2::resp_status() |
| KenPom session authentication | rvest::session() with httr cookies |
httr2 cookie-jar via login() /
.kp_get_page() / .kp_request() helpers |
| libcurl >= 8.x / curl R >= 7.0.0 segfaults | Triggered | Resolved (httr2 does not have the affected code
path) |
Note: proxy plumbing on request_with_proxy() was
quietly dropped during this migration. The restoration shipped in
3.1.0 — see above.
usethis::ui_*() messaging calls in
database builder and loader functions with cli
equivalents.| Old call | New call |
|---|---|
usethis::ui_stop() |
cli::cli_abort() |
usethis::ui_oops() |
cli::cli_alert_danger() |
usethis::ui_todo() |
cli::cli_ul() |
usethis::ui_info() |
cli::cli_alert_info() |
usethis::ui_value() |
{.val} inline markup |
usethis::ui_path() |
{.file} inline markup |
usethis::ui_code() |
{.code} inline markup |
usethis from Imports to
Suggests (retained for
usethis::edit_r_environ() documentation references).nba_playercareerstats(),
nba_playerdashptshotdefend(), and
nba_playerprofilev2()).nba_playerprofilev2() assertions to validate
core columns while tolerating empty optional result sets.expect_equal(colnames()) assertions to
expect_in() for subset validation, preventing test failures
when APIs add new columns.skip_ncaa_mbb_test() and
skip_ncaa_wbb_test() helpers.nbagl_players() and nbagl_standings()
named-list returns, and current schedule/PBP core columns).Dependency status before / after the release. Users with strict dependency pinning or downstream packages that re-export hoopR functionality should review this table.
| Dependency | Before (2.1.0) | After (3.0.0) | Why |
|---|---|---|---|
httr |
Imports |
Removed | Replaced by httr2 (see HTTP migration above) |
httr2 |
— | Imports |
New HTTP backend |
usethis |
Imports |
Suggests |
Messaging migration to cli; retained only for
usethis::edit_r_environ() doc references |
furrr |
Imports |
Suggests |
Optional parallel features only; not required for core functionality |
future |
Imports |
Suggests |
Same as furrr — optional parallel features |
lifecycle |
— | Imports |
Required for the new lifecycle::deprecate_stop()
deprecation pattern |
qs |
Imports |
Removed | No longer used by any code path |
.Rbuildignore duplicates.nba_endpoint() registry updated with all V3
boxscore endpoints and boxscoresummaryv3.CONTRIBUTING.md with naming
conventions and test environment documentation.logo=twitter → logo=x;
profile URLs twitter.com → x.com.fa-twitter to
fa-x-twitter.load_nba_*() functions now use
sportsdataverse-data releases url instead of
hoopR-data repository URLload_mbb_*() functions now use
sportsdataverse-data releases url instead of
hoopR-data repository URLnba_pbp() and nba_pbps() functions add
parameter on_court (default TRUE) to return
on-court players for each play event, courtesy of @shufinskiynba_live_pbp() function added.nba_live_boxscore() function added.nba_todays_scoreboard() function added.nba_scoreboardv3() function added.nba_boxscoretraditionalv3() function added.nba_boxscoreadvancedv3() function added.nba_boxscoremiscv3() function added.nba_boxscorescoringv3() function added.nba_boxscoreusagev3() function added.nba_boxscorefourfactorsv3() function added.nba_boxscoreplayertrackv3() function added.nba_boxscorematchupsv3() function added.nba_boxscorehustlev2() function added.nba_boxscoredefensivev2() function added.nba_shotchartlineupdetail() function added.nba_synergyplaytypes() function added.nba_franchiseleaderswrank() function added.nba_videodetailsasset() function added.nba_infographicfanduelplayer() function added.nba_teams() function added.ncaa_mbb_teams() function added.httr::use_proxy()
option to nba_*() functionskp_* functionsespn_mbb_game_rosters() function added.espn_nba_game_rosters() function added.espn_mbb_player_stats() function exported
properly.espn_nba_player_stats() function exported
properly.kp_ functions.espn_mbb_player_stats() function added.espn_mbb_team_stats() function added.espn_nba_player_stats() function added.espn_nba_team_stats() function added.nba_pbps() function added, courtesy of @papagorgio23.nbagl_players() function added, courtesy of @billyfryer.nbagl_schedule() function added, courtesy of @billyfryer.nbagl_pbp() function added, courtesy of @billyfryer.nbagl_standings() function added, courtesy of @billyfryer.nba_gamerotation() function added.nba_playerindex() function added.nba_playerheadshot() function added.nba_drafthistory() function added.kp_referee() functionkp_box() functionnba_boxscore(.*) functionsteams_links internal dataset for 2022 (need a
better solve here)nba_teams dataset for working with the NBA Stats
APIhoopR::espn_mbb_betting()
function addedhoopR::espn_nba_betting()
function addedkp_winprob
function, adding runs as third outputAdding roughly 127 functions
| Function | File Location |
|---|---|
| nba_alltimeleadersgrids | R/nba_stats_leaders.R |
| nba_assistleaders | R/nba_stats_leaders.R |
| nba_assisttracker | R/nba_stats_leaders.R |
| nba_boxscoreadvancedv2 | R/nba_stats_boxscore.R |
| nba_boxscoredefensive | R/nba_stats_boxscore.R |
| nba_boxscorefourfactorsv2 | R/nba_stats_boxscore.R |
| nba_boxscorematchups | R/nba_stats_boxscore.R |
| nba_boxscoremiscv2 | R/nba_stats_boxscore.R |
| nba_boxscoreplayertrackv2 | R/nba_stats_boxscore.R |
| nba_boxscorescoringv2 | R/nba_stats_boxscore.R |
| nba_boxscoresimilarityscore | R/nba_stats_boxscore.R |
| nba_boxscoresummaryv2 | R/nba_stats_boxscore.R |
| nba_boxscoretraditionalv2 | R/nba_stats_boxscore.R |
| nba_boxscoreusagev2 | R/nba_stats_boxscore.R |
| nba_commonallplayers | R/nba_stats_roster.R |
| nba_commonplayerinfo | R/nba_stats_roster.R |
| nba_commonplayoffseries | R/nba_stats_roster.R |
| nba_commonteamroster | R/nba_stats_roster.R |
| nba_cumestatsplayer | R/nba_stats_cume.R |
| nba_cumestatsplayergames | R/nba_stats_cume.R |
| nba_cumestatsteam | R/nba_stats_cume.R |
| nba_cumestatsteamgames | R/nba_stats_cume.R |
| nba_defensehub | R/nba_stats_leaders.R |
| nba_draftboard | R/nba_stats_draft.R |
| nba_draftcombinedrillresults | R/nba_stats_draft.R |
| nba_draftcombinenonstationaryshooting | R/nba_stats_draft.R |
| nba_draftcombineplayeranthro | R/nba_stats_draft.R |
| nba_draftcombinespotshooting | R/nba_stats_draft.R |
| nba_draftcombinestats | R/nba_stats_draft.R |
| nba_fantasywidget | R/nba_stats_lineups.R |
| nba_franchisehistory | R/nba_stats_franchise.R |
| nba_franchiseleaders | R/nba_stats_franchise.R |
| nba_franchiseplayers | R/nba_stats_franchise.R |
| nba_glalumboxscoresimilarityscore | R/nba_stats_boxscore.R |
| nba_homepageleaders | R/nba_stats_leaders.R |
| nba_homepagev2 | R/nba_stats_leaders.R |
| nba_hustlestatsboxscore | R/nba_stats_boxscore.R |
| nba_leaderstiles | R/nba_stats_leaders.R |
| nba_leaguedashlineups | R/nba_stats_lineups.R |
| nba_leaguedashoppptshot | R/nba_stats_league_dash.R |
| nba_leaguedashplayerbiostats | R/nba_stats_league_dash.R |
| nba_leaguedashplayerclutch | R/nba_stats_league_dash.R |
| nba_leaguedashplayerptshot | R/nba_stats_league_dash.R |
| nba_leaguedashplayershotlocations | R/nba_stats_league_dash.R |
| nba_leaguedashplayerstats | R/nba_stats_league_dash.R |
| nba_leaguedashptdefend | R/nba_stats_league_dash.R |
| nba_leaguedashptstats | R/nba_stats_league_dash.R |
| nba_leaguedashptteamdefend | R/nba_stats_league_dash.R |
| nba_leaguedashteamclutch | R/nba_stats_league_dash.R |
| nba_leaguedashteamptshot | R/nba_stats_league_dash.R |
| nba_leaguedashteamshotlocations | R/nba_stats_league_dash.R |
| nba_leaguedashteamstats | R/nba_stats_league_dash.R |
| nba_leaguegamefinder | R/nba_stats_league.R |
| nba_leaguegamelog | R/nba_stats_league.R |
| nba_leaguehustlestatsplayer | R/nba_stats_hustle.R |
| nba_leaguehustlestatsplayerleaders | R/nba_stats_hustle.R |
| nba_leaguehustlestatsteam | R/nba_stats_hustle.R |
| nba_leaguehustlestatsteamleaders | R/nba_stats_hustle.R |
| nba_leagueleaders | R/nba_stats_leaders.R |
| nba_leaguelineupviz | R/nba_stats_lineups.R |
| nba_leagueplayerondetails | R/nba_stats_lineups.R |
| nba_leagueseasonmatchups | R/nba_stats_lineups.R |
| nba_leaguestandings | R/nba_stats_league.R |
| nba_leaguestandingsv3 | R/nba_stats_league.R |
| nba_matchupsrollup | R/nba_stats_lineups.R |
| nba_pbp | R/nba_stats_pbp.R |
| nba_playerawards | R/nba_stats_player.R |
| nba_playercareerbycollege | R/nba_stats_player.R |
| nba_playercareerbycollegerollup | R/nba_stats_player.R |
| nba_playercareerstats | R/nba_stats_player.R |
| nba_playercompare | R/nba_stats_player.R |
| nba_playerdashboardbyclutch | R/nba_stats_player_dash.R |
| nba_playerdashboardbygamesplits | R/nba_stats_player_dash.R |
| nba_playerdashboardbygeneralsplits | R/nba_stats_player_dash.R |
| nba_playerdashboardbylastngames | R/nba_stats_player_dash.R |
| nba_playerdashboardbyopponent | R/nba_stats_player_dash.R |
| nba_playerdashboardbyshootingsplits | R/nba_stats_player_dash.R |
| nba_playerdashboardbyteamperformance | R/nba_stats_player_dash.R |
| nba_playerdashboardbyyearoveryear | R/nba_stats_player_dash.R |
| nba_playerdashptpass | R/nba_stats_player_dash.R |
| nba_playerdashptreb | R/nba_stats_player_dash.R |
| nba_playerdashptshotdefend | R/nba_stats_player_dash.R |
| nba_playerdashptshots | R/nba_stats_player_dash.R |
| nba_playerestimatedmetrics | R/nba_stats_player.R |
| nba_playerfantasyprofile | R/nba_stats_player.R |
| nba_playerfantasyprofilebargraph | R/nba_stats_player.R |
| nba_playergamelog | R/nba_stats_player.R |
| nba_playergamelogs | R/nba_stats_player.R |
| nba_playergamestreakfinder | R/nba_stats_player.R |
| nba_playernextngames | R/nba_stats_player.R |
| nba_playerprofilev2 | R/nba_stats_player.R |
| nba_playervsplayer | R/nba_stats_player.R |
| nba_playoffpicture | R/nba_stats_league.R |
| nba_schedule | R/nba_stats_pbp.R |
| nba_scoreboard | R/nba_stats_scoreboard.R |
| nba_scoreboardv2 | R/nba_stats_scoreboard.R |
| nba_shotchartdetail | R/nba_stats_shotchart.R |
| nba_shotchartleaguewide | R/nba_stats_shotchart.R |
| nba_teamdashboardbyclutch | R/nba_stats_team_dash.R |
| nba_teamdashboardbygamesplits | R/nba_stats_team_dash.R |
| nba_teamdashboardbygeneralsplits | R/nba_stats_team_dash.R |
| nba_teamdashboardbylastngames | R/nba_stats_team_dash.R |
| nba_teamdashboardbyopponent | R/nba_stats_team_dash.R |
| nba_teamdashboardbyshootingsplits | R/nba_stats_team_dash.R |
| nba_teamdashboardbyteamperformance | R/nba_stats_team_dash.R |
| nba_teamdashboardbyyearoveryear | R/nba_stats_team_dash.R |
| nba_teamdashlineups | R/nba_stats_team_dash.R |
| nba_teamdashptpass | R/nba_stats_team_dash.R |
| nba_teamdashptreb | R/nba_stats_team_dash.R |
| nba_teamdashptshots | R/nba_stats_team_dash.R |
| nba_teamdetails | R/nba_stats_team.R |
| nba_teamestimatedmetrics | R/nba_stats_team.R |
| nba_teamgamelog | R/nba_stats_team.R |
| nba_teamgamelogs | R/nba_stats_team.R |
| nba_teamgamestreakfinder | R/nba_stats_team.R |
| nba_teamhistoricalleaders | R/nba_stats_team.R |
| nba_teaminfocommon | R/nba_stats_team.R |
| nba_teamplayerdashboard | R/nba_stats_team.R |
| nba_teamplayeronoffdetails | R/nba_stats_team.R |
| nba_teamplayeronoffsummary | R/nba_stats_team.R |
| nba_teamvsplayer | R/nba_stats_team.R |
| nba_teamyearbyyearstats | R/nba_stats_team.R |
| nba_videodetails | R/nba_stats_video.R |
| nba_videoevents | R/nba_stats_video.R |
| nba_videostatus | R/nba_stats_video.R |
| nba_winprobabilitypbp | R/nba_stats_scoreboard.R |
hoopR::load_mbb_schedule()
function addedhoopR::load_nba_schedule()
function addedhoopR::load_mbb_team_box()
function addedhoopR::load_nba_team_box()
function addedhoopR::load_mbb_player_box()
function addedhoopR::load_nba_player_box()
function addedhttr::retry()
to all function calls to more naturally navigate rejected/failed
requests from the API.This update is a non-user facing change to package dependencies to shrink the list of dependencies.
To reflect that the package is no longer just a men’s college basketball and KenPom package, but also an NBA package.
janitor::clean_names()
treatmenthoopR::espn_mbb_teams()
has updated the returns to be more identity information related
onlyhoopR::espn_nba_teams()
to be more identity information related onlyhoopR::load_mbb_pbp()
and hoopR::update_mbb_db()
functions addedhoopR::load_nba_pbp()
and hoopR::update_nba_db()
functions addedhoopR::espn_nba_game_all() - a convenience wrapper
function around the following three functions (returns the results as a
list of three data frames)hoopR::espn_nba_team_box()hoopR::espn_nba_player_box()hoopR::espn_nba_pbp()hoopR::espn_nba_teams()hoopR::espn_nba_scoreboard()R version 3.5.0 or greater dependency addedpurrr version 0.3.0 or greater dependency addedrvest version 1.0.0 or greater dependency addedprogressr version 0.6.0 or greater dependency
addedusethis version 1.6.0 or greater dependency addedxgboost version 1.1.0 or greater dependency addedtidyr version 1.0.0 or greater dependency addedstringr version 1.3.0 or greater dependency addedtibble version 3.0.0 or greater dependency addedfurrr dependency addedfuture dependency addedkp_ as opposed to get_espn_ as opposed to cbb_. Moreover, all
references to cbb_ have been changed to mbb_
as appropriate.ncaa_hoopR::espn_mbb_game_all() - a convenience wrapper
function around the following three functions (returns the results as a
list of three data frames)hoopR::espn_mbb_team_box()hoopR::espn_mbb_player_box()hoopR::espn_mbb_pbp()hoopR::espn_mbb_teams() (bumps to v0.2.1)hoopR::espn_mbb_conferences() (bumps to v0.2.1)hoopR::espn_mbb_scoreboard() (bumps to v0.2.2)hoopR::ncaa_mbb_NET_rankings() (bumps to v0.2.3)hoopR::espn_mbb_rankings() (bumps to v0.2.3)Initial Commits, remaining tasks: