Since it’s steady legalization throughout the United States, sports betting as an industry has grown expeditiously. With more and more Americans participating every day, I wanted to take a closer look at the numbers and odds people are betting their money so freely on. Due to their convoluted nature, looking through betting odds can be incredibly difficult to fully grasp when attempting to decipher one’s actual chance of winning a bet. In this project, I aim to gather more information into how sportsbooks create their odds, and any inconsistencies they may have.

# Storing API to remove public visibility
setwd("C:\\Users\\poiso\\OneDrive\\Documents\\Data607FinalProject")
source("config.R")
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
# Path to nfl outcome dataset
file_path <- "https://raw.githubusercontent.com/zachrose97/Data607Final/refs/heads/main/sportsref_download%20(6).csv"

# Load the dataset
nfl_data <- read_csv(file_path)
## New names:
## Rows: 286 Columns: 14
## ── Column specification
## ──────────────────────────────────────────────────────── Delimiter: "," chr
## (7): Week, Day, Date, Winner/tie, ...6, Loser/tie, ...8 dbl (6): PtsW, PtsL,
## YdsW, TOW, YdsL, TOL time (1): Time
## ℹ Use `spec()` to retrieve the full column specification for this data. ℹ
## Specify the column types or set `show_col_types = FALSE` to quiet this message.
## • `` -> `...6`
## • `` -> `...8`
glimpse(nfl_data)
## Rows: 286
## Columns: 14
## $ Week         <chr> "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1…
## $ Day          <chr> "Thu", "Sun", "Sun", "Sun", "Sun", "Sun", "Sun", "Sun", "…
## $ Date         <chr> "9/7/2023", "9/10/2023", "9/10/2023", "9/10/2023", "9/10/…
## $ Time         <time> 20:20:00, 13:00:00, 13:00:00, 13:00:00, 13:00:00, 13:00:…
## $ `Winner/tie` <chr> "Detroit Lions", "Atlanta Falcons", "Cleveland Browns", "…
## $ ...6         <chr> "@", NA, NA, "@", NA, NA, "@", NA, "@", "@", "@", "@", "@…
## $ `Loser/tie`  <chr> "Kansas City Chiefs", "Carolina Panthers", "Cincinnati Be…
## $ ...8         <chr> "boxscore", "boxscore", "boxscore", "boxscore", "boxscore…
## $ PtsW         <dbl> 21, 24, 24, 31, 20, 25, 20, 16, 30, 38, 17, 36, 25, 30, 4…
## $ PtsL         <dbl> 20, 10, 3, 21, 16, 9, 17, 15, 7, 20, 16, 34, 20, 13, 0, 1…
## $ YdsW         <dbl> 368, 221, 350, 342, 248, 265, 242, 351, 391, 329, 261, 53…
## $ TOW          <dbl> 1, 0, 2, 2, 3, 2, 0, 2, 1, 0, 1, 2, 1, 0, 0, 1, 1, 1, 0, …
## $ YdsL         <dbl> 316, 281, 142, 280, 210, 268, 369, 285, 239, 311, 260, 43…
## $ TOL          <dbl> 1, 3, 0, 3, 2, 1, 3, 3, 2, 2, 0, 0, 2, 0, 3, 4, 4, 0, 3, …
# Column name adjustment
nfl_data <- nfl_data %>%
  rename(
    week = Week,
    day = Day,
    game_date = Date,
    game_time = Time,
    winner = `Winner/tie`,
    location = `...6`,
    loser = `Loser/tie`,
    winner_points = PtsW,
    loser_points = PtsL,
    winner_yards = YdsW,
    winner_turnovers = TOW,
    loser_yards = YdsL,
    loser_turnovers = TOL
  )
# Data clean up
nfl_data <- nfl_data %>%
  filter(!is.na(game_date))
sum(is.na(nfl_data$game_date))
## [1] 0
library(rvest)
## 
## Attaching package: 'rvest'
## The following object is masked from 'package:readr':
## 
##     guess_encoding
# Define the URL for Week 1 of web scraping data
url <- "https://www.sportsoddshistory.com/nfl-game-season/?y=2023&week=1"

# Read the webpage
webpage <- read_html(url)

# Extract all tables on the page
all_tables <- webpage %>% html_nodes("table")

# Print the total number of tables
length(all_tables)
## [1] 26
# Inspects the first few tables
for (i in seq_along(all_tables)) {
  cat("\n--- Table", i, "---\n")
  print(all_tables[[i]] %>% html_table(fill = TRUE) %>% head())
}
## 
## --- Table 1 ---
## # A tibble: 6 × 209
##   X1     X2    X3    X4    X5    X6    X7    X8    X9    X10   X11   X12   X13  
##   <chr>  <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 "Week… Week  Favo… Favo… Home… Home… Home… Home… Home… Home… Over… Stra… ATS  
## 2 "Week" Week  Favo… Favo… Home… Home… Home… Home… Home… Home… Over… Over… <NA> 
## 3 "Week" Stra… ATS   Stra… ATS   Stra… ATS   Stra… ATS   <NA>  <NA>  Over… <NA> 
## 4 "1"    8-8 … 6-10… 6-10… 4-12… 4-6 … 2-8-… 2-4 … 2-4-… 3-13… <NA>  <NA>  <NA> 
## 5 "2"    10-6… 5-9-… 7-9 … 7-7-… 5-4 … 3-5-… 2-5 … 4-2-… 13-3… <NA>  <NA>  <NA> 
## 6 "3"    11-5… 9-6-… 9-7 … 7-8-… 8-4 … 6-5-… 1-3 … 1-3-… 5-11… <NA>  <NA>  <NA> 
## # ℹ 196 more variables: X14 <chr>, X15 <chr>, X16 <chr>, X17 <chr>, X18 <chr>,
## #   X19 <chr>, X20 <int>, X21 <chr>, X22 <chr>, X23 <chr>, X24 <chr>,
## #   X25 <chr>, X26 <chr>, X27 <chr>, X28 <chr>, X29 <chr>, X30 <int>,
## #   X31 <chr>, X32 <chr>, X33 <chr>, X34 <chr>, X35 <chr>, X36 <chr>,
## #   X37 <chr>, X38 <chr>, X39 <chr>, X40 <int>, X41 <chr>, X42 <chr>,
## #   X43 <chr>, X44 <chr>, X45 <chr>, X46 <chr>, X47 <chr>, X48 <chr>,
## #   X49 <chr>, X50 <int>, X51 <chr>, X52 <chr>, X53 <chr>, X54 <chr>, …
## 
## --- Table 2 ---
## # A tibble: 6 × 10
##   Week  Favorites    Favorites   HomeTeams HomeTeams HomeFavorites HomeFavorites
##   <chr> <chr>        <chr>       <chr>     <chr>     <chr>         <chr>        
## 1 Week  StraightUp   ATS         Straight… ATS       StraightUp    ATS          
## 2 1     8-8 (50.0%)  6-10-0  (3… 6-10 (37… 4-12-0 (… 4-6 (40.0%)   2-8-0 (20.0%)
## 3 2     10-6 (62.5%) 5-9-2  (35… 7-9 (43.… 7-7-2 (5… 5-4 (55.6%)   3-5-1 (37.5%)
## 4 3     11-5 (68.8%) 9-6-1  (60… 9-7 (56.… 7-8-1 (4… 8-4 (66.7%)   6-5-1 (54.5%)
## 5 4     13-3 (81.3%) 10-5-1  (6… 7-8 (46.… 7-7-1 (5… 5-1 (83.3%)   4-2-0 (66.7%)
## 6 5     8-6 (57.1%)  7-7-0  (50… 7-6 (53.… 6-7-0 (4… 5-3 (62.5%)   4-4-0 (50.0%)
## # ℹ 3 more variables: HomeUnderdogs <chr>, HomeUnderdogs <chr>,
## #   `Over/Unders` <chr>
## 
## --- Table 3 ---
## # A tibble: 6 × 3,685
##   X1     X2    X3    X4    X5    X6    X7    X8    X9    X10   X11   X12   X13  
##   <chr>  <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 "Team… Team  Over… Over… Favo… Favo… Home  Home  Home… Home… Over… Stra… ATS  
## 2 "Team… Team  Team  Over… Over… Favo… Favo… Home  Home  Home… Home… Over… Stra…
## 3 "Team" Over… Over… Favo… Favo… Home  Home  Home… Home… Over… <NA>  Over… <NA> 
## 4 "Team" Stra… ATS   Stra… ATS   Stra… ATS   Stra… ATS   Over… <NA>  <NA>  <NA> 
## 5 "Ariz… 4-13… 9-8 … 0-0   0-0-0 2-6 … 5-3-… 0-0   0-0-0 10-7… <NA>  <NA>  <NA> 
## 6 "Atla… 7-10… 5-12… 5-6 … 3-8-… 5-3 … 3-5-… 4-3 … 2-5-… 7-10… <NA>  <NA>  <NA> 
## # ℹ 3,672 more variables: X14 <chr>, X15 <chr>, X16 <chr>, X17 <chr>,
## #   X18 <chr>, X19 <chr>, X20 <chr>, X21 <chr>, X22 <chr>, X23 <chr>,
## #   X24 <chr>, X25 <chr>, X26 <chr>, X27 <chr>, X28 <chr>, X29 <chr>,
## #   X30 <chr>, X31 <chr>, X32 <chr>, X33 <chr>, X34 <chr>, X35 <chr>,
## #   X36 <chr>, X37 <chr>, X38 <chr>, X39 <chr>, X40 <chr>, X41 <chr>,
## #   X42 <chr>, X43 <chr>, X44 <chr>, X45 <chr>, X46 <chr>, X47 <chr>,
## #   X48 <chr>, X49 <chr>, X50 <chr>, X51 <chr>, X52 <chr>, X53 <chr>, …
## 
## --- Table 4 ---
## # A tibble: 6 × 339
##   X1     X2    X3    X4    X5    X6    X7    X8    X9    X10   X11   X12   X13  
##   <chr>  <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 "Team… Team  Over… Over… Favo… Favo… Home  Home  Home… Home… Over… Stra… ATS  
## 2 "Team" Team  Over… Over… Favo… Favo… Home  Home  Home… Home… Over… Over… <NA> 
## 3 "Team" Stra… ATS   Stra… ATS   Stra… ATS   Stra… ATS   <NA>  <NA>  Over… <NA> 
## 4 "Ariz… 4-13… 9-8 … 0-0   0-0-0 2-6 … 5-3-… 0-0   0-0-0 10-7… <NA>  <NA>  <NA> 
## 5 "Atla… 7-10… 5-12… 5-6 … 3-8-… 5-3 … 3-5-… 4-3 … 2-5-… 7-10… <NA>  <NA>  <NA> 
## 6 "Balt… 13-4… 11-6… 11-3… 9-5-… 6-3 … 5-4-… 6-2 … 5-3-… 8-9-… <NA>  <NA>  <NA> 
## # ℹ 326 more variables: X14 <chr>, X15 <chr>, X16 <chr>, X17 <chr>, X18 <chr>,
## #   X19 <chr>, X20 <chr>, X21 <chr>, X22 <chr>, X23 <chr>, X24 <chr>,
## #   X25 <chr>, X26 <chr>, X27 <chr>, X28 <chr>, X29 <chr>, X30 <chr>,
## #   X31 <chr>, X32 <chr>, X33 <chr>, X34 <chr>, X35 <chr>, X36 <chr>,
## #   X37 <chr>, X38 <chr>, X39 <chr>, X40 <chr>, X41 <chr>, X42 <chr>,
## #   X43 <chr>, X44 <chr>, X45 <chr>, X46 <chr>, X47 <chr>, X48 <chr>,
## #   X49 <chr>, X50 <chr>, X51 <chr>, X52 <chr>, X53 <chr>, X54 <chr>, …
## 
## --- Table 5 ---
## # A tibble: 6 × 10
##   Team   Overall Overall Favorite Favorite Home  Home  HomeFavorite HomeFavorite
##   <chr>  <chr>   <chr>   <chr>    <chr>    <chr> <chr> <chr>        <chr>       
## 1 Team   Straig… ATS     Straigh… ATS      Stra… ATS   StraightUp   ATS         
## 2 Arizo… 4-13 (… 9-8  (… 0-0      0-0-0    2-6 … 5-3-… 0-0          0-0-0       
## 3 Atlan… 7-10 (… 5-12  … 5-6 (45… 3-8-0  … 5-3 … 3-5-… 4-3 (57.1%)  2-5-0 (28.6…
## 4 Balti… 13-4 (… 11-6  … 11-3 (7… 9-5-0  … 6-3 … 5-4-… 6-2 (75.0%)  5-3-0 (62.5…
## 5 Buffa… 11-6 (… 7-10  … 10-4 (7… 6-8-0  … 7-1 … 4-4-… 7-1 (87.5%)  4-4-0 (50.0…
## 6 Carol… 2-15 (… 5-11-1… 0-0      0-0-0    2-6 … 3-4-… 0-0          0-0-0       
## # ℹ 1 more variable: `Over/Unders` <chr>
## 
## --- Table 6 ---
## # A tibble: 6 × 3,345
##   X1     X2    X3    X4    X5    X6    X7    X8    X9    X10   X11   X12   X13  
##   <chr>  <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 "Back… Day   Date  "Tim… ""    Favo… Score "Spr… ""    Unde… "Ove… "Not… Thu  
## 2 "Day"  Date  Time… ""    "Fav… Score Spre… ""    "Und… Over… "Not… "Not… <NA> 
## 3 "Thu"  Sep … 8:20  "@"   "Kan… L 20… L -4  ""    "Det… U 53… "Not… ""    <NA> 
## 4 "Sun"  Sep … 1:00  "@"   "Atl… W 24… W -3  ""    "Car… U 43  ""     <NA> <NA> 
## 5 "Sun"  Sep … 1:00  "@"   "Bal… W 25… W -9  ""    "Hou… U 44… ""     <NA> <NA> 
## 6 "Sun"  Sep … 1:00  "@"   "Chi… L 20… L -2… ""    "Gre… O 44… ""     <NA> <NA> 
## # ℹ 3,332 more variables: X14 <chr>, X15 <chr>, X16 <chr>, X17 <chr>,
## #   X18 <chr>, X19 <chr>, X20 <lgl>, X21 <chr>, X22 <chr>, X23 <lgl>,
## #   X24 <chr>, X25 <chr>, X26 <chr>, X27 <chr>, X28 <chr>, X29 <chr>,
## #   X30 <chr>, X31 <lgl>, X32 <chr>, X33 <chr>, X34 <lgl>, X35 <chr>,
## #   X36 <chr>, X37 <chr>, X38 <chr>, X39 <chr>, X40 <chr>, X41 <chr>,
## #   X42 <lgl>, X43 <chr>, X44 <chr>, X45 <lgl>, X46 <chr>, X47 <chr>,
## #   X48 <chr>, X49 <chr>, X50 <chr>, X51 <chr>, X52 <chr>, X53 <lgl>, …
## 
## --- Table 7 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Sep 7, 2023  8:20        "@"   Kansas City … L 20… L -4   ""    Detroit…
## 2 Sun   Sep 10, 2023 1:00        "@"   Atlanta Falc… W 24… W -3   ""    Carolin…
## 3 Sun   Sep 10, 2023 1:00        "@"   Baltimore Ra… W 25… W -9   ""    Houston…
## 4 Sun   Sep 10, 2023 1:00        "@"   Chicago Bears L 20… L -2.5 ""    Green B…
## 5 Sun   Sep 10, 2023 1:00        ""    Cincinnati B… L 3-… L -1   "@"   Clevela…
## 6 Sun   Sep 10, 2023 1:00        ""    Jacksonville… W 31… W -3.5 "@"   Indiana…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 8 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Sep 14, 2023 8:15        @     Philadelphia… W 34… P -6   ""    Minneso…
## 2 Sun   Sep 17, 2023 1:00        @     Atlanta Falc… W 25… L -3   ""    Green B…
## 3 Sun   Sep 17, 2023 1:00        @     Buffalo Bills W 38… W -8   ""    Las Veg…
## 4 Sun   Sep 17, 2023 1:00        @     Cincinnati B… L 24… L -3.5 ""    Baltimo…
## 5 Sun   Sep 17, 2023 1:00        @     Detroit Lions L 31… L -4.5 ""    Seattle…
## 6 Sun   Sep 17, 2023 1:00        @     Houston Texa… L 20… L -1   ""    Indiana…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 9 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Sep 21, 2023 8:15        @     San Francisc… W 30… W -10… ""    New Yor…
## 2 Sun   Sep 24, 2023 1:00        @     Baltimore Ra… L 19… L -7.5 ""    Indiana…
## 3 Sun   Sep 24, 2023 1:00        @     Cleveland Br… W 27… W -3.5 ""    Tenness…
## 4 Sun   Sep 24, 2023 1:00        @     Detroit Lions W 20… W -3   ""    Atlanta…
## 5 Sun   Sep 24, 2023 1:00        @     Green Bay Pa… W 18… L -1.5 ""    New Orl…
## 6 Sun   Sep 24, 2023 1:00        @     Jacksonville… L 17… L -9.5 ""    Houston…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 10 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Sep 28, 2023 8:15        ""    Detroit Lions W 34… W -2.5 "@"   Green B…
## 2 Sun   Oct 1, 2023  9:30        "N"   Jacksonville… W 23… W -3.5 ""    Atlanta…
## 3 Sun   Oct 1, 2023  1:00        "@"   Buffalo Bills W 48… W -2.5 ""    Miami D…
## 4 Sun   Oct 1, 2023  1:00        ""    Minnesota Vi… W 21… W -4.5 "@"   Carolin…
## 5 Sun   Oct 1, 2023  1:00        ""    Denver Bronc… W 31… P -3   "@"   Chicago…
## 6 Sun   Oct 1, 2023  1:00        ""    Baltimore Ra… W 28… W -2.5 "@"   Clevela…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 11 ---
## # A tibble: 6 × 12
##   Day   Date        `Time (ET)` ``    Favorite       Score Spread ``    Underdog
##   <chr> <chr>       <chr>       <chr> <chr>          <chr> <chr>  <chr> <chr>   
## 1 Thu   Oct 5, 2023 8:15        "@"   Washington Co… L 20… L -6   ""    Chicago…
## 2 Sun   Oct 8, 2023 9:30        "N"   Buffalo Bills  L 20… L -5.5 ""    Jackson…
## 3 Sun   Oct 8, 2023 1:00        "@"   Atlanta Falco… W 21… L -2.5 ""    Houston…
## 4 Sun   Oct 8, 2023 1:00        "@"   Detroit Lions  W 42… W -9.5 ""    Carolin…
## 5 Sun   Oct 8, 2023 1:00        ""    Tennessee Tit… L 16… L -2.5 "@"   Indiana…
## 6 Sun   Oct 8, 2023 1:00        "@"   Miami Dolphins W 31… W -13  ""    New Yor…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 12 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Oct 12, 2023 8:15        "@"   Kansas City … W 19… W -10… ""    Denver …
## 2 Sun   Oct 15, 2023 9:30        "N"   Baltimore Ra… W 24… W -5   ""    Tenness…
## 3 Sun   Oct 15, 2023 1:00        "@"   Atlanta Falc… L 16… L -1.5 ""    Washing…
## 4 Sun   Oct 15, 2023 1:00        ""    Minnesota Vi… W 19… W -3   "@"   Chicago…
## 5 Sun   Oct 15, 2023 1:00        "@"   Cincinnati B… W 17… W -3   ""    Seattle…
## 6 Sun   Oct 15, 2023 1:00        ""    San Francisc… L 17… L -9.5 "@"   Clevela…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 13 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Oct 19, 2023 8:15        "@"   New Orleans … L 24… L -2.5 ""    Jackson…
## 2 Sun   Oct 22, 2023 1:00        "@"   Baltimore Ra… W 38… W -3   ""    Detroit…
## 3 Sun   Oct 22, 2023 1:00        ""    Las Vegas Ra… L 12… L -2.5 "@"   Chicago…
## 4 Sun   Oct 22, 2023 1:00        ""    Cleveland Br… W 39… L -3.5 "@"   Indiana…
## 5 Sun   Oct 22, 2023 1:00        ""    Buffalo Bills L 25… L -7.5 "@"   New Eng…
## 6 Sun   Oct 22, 2023 1:00        ""    Washington C… L 7-… L -3   "@"   New Yor…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 14 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Oct 26, 2023 8:15        "@"   Buffalo Bills W 24… L -10  ""    Tampa B…
## 2 Sun   Oct 29, 2023 1:00        ""    Houston Texa… L 13… L -3.5 "@"   Carolin…
## 3 Sun   Oct 29, 2023 1:00        "@"   Dallas Cowbo… W 43… W -6.5 ""    Los Ang…
## 4 Sun   Oct 29, 2023 1:00        ""    Minnesota Vi… W 24… W -1.5 "@"   Green B…
## 5 Sun   Oct 29, 2023 1:00        ""    New Orleans … W 38… W -1.5 "@"   Indiana…
## 6 Sun   Oct 29, 2023 1:00        "@"   Miami Dolphi… W 31… W -8.5 ""    New Eng…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 15 ---
## # A tibble: 6 × 12
##   Day   Date        `Time (ET)` ``    Favorite       Score Spread ``    Underdog
##   <chr> <chr>       <chr>       <chr> <chr>          <chr> <chr>  <chr> <chr>   
## 1 Thu   Nov 2, 2023 8:15        @     Pittsburgh St… W 20… W -3   ""    Tenness…
## 2 Sun   Nov 5, 2023 9:30        N     Kansas City C… W 21… W -1.5 ""    Miami D…
## 3 Sun   Nov 5, 2023 1:00        @     Atlanta Falco… L 28… L -3.5 ""    Minneso…
## 4 Sun   Nov 5, 2023 1:00        @     Baltimore Rav… W 37… W -6.5 ""    Seattle…
## 5 Sun   Nov 5, 2023 1:00        @     Cleveland Bro… W 27… W -13… ""    Arizona…
## 6 Sun   Nov 5, 2023 1:00        @     Green Bay Pac… W 20… W -3.5 ""    Los Ang…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 16 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Nov 9, 2023  8:15        "@"   Chicago Bears W 16… L -3.5 ""    Carolin…
## 2 Sun   Nov 12, 2023 9:30        "N"   Indianapolis… W 10… W -2.5 ""    New Eng…
## 3 Sun   Nov 12, 2023 1:00        "@"   Baltimore Ra… L 31… L -6   ""    Clevela…
## 4 Sun   Nov 12, 2023 1:00        "@"   Cincinnati B… L 27… L -5.5 ""    Houston…
## 5 Sun   Nov 12, 2023 1:00        ""    San Francisc… W 34… W -3   "@"   Jackson…
## 6 Sun   Nov 12, 2023 1:00        ""    New Orleans … L 19… L -2.5 "@"   Minneso…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 17 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Nov 16, 2023 8:15        "@"   Baltimore Ra… W 34… W -3.5 ""    Cincinn…
## 2 Sun   Nov 19, 2023 1:00        ""    Dallas Cowbo… W 33… W -11  "@"   Carolin…
## 3 Sun   Nov 19, 2023 1:00        "@"   Cleveland Br… W 13… W -1.5 ""    Pittsbu…
## 4 Sun   Nov 19, 2023 1:00        "@"   Detroit Lions W 31… L -7.5 ""    Chicago…
## 5 Sun   Nov 19, 2023 1:00        ""    Los Angeles … L 20… L -3   "@"   Green B…
## 6 Sun   Nov 19, 2023 1:00        "@"   Houston Texa… W 21… L -5.5 ""    Arizona…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 18 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Nov 23, 2023 12:30       "@"   Detroit Lions L 22… L -8.5 ""    Green B…
## 2 Thu   Nov 23, 2023 4:30        "@"   Dallas Cowbo… W 45… W -13… ""    Washing…
## 3 Thu   Nov 23, 2023 8:20        ""    San Francisc… W 31… W -7   "@"   Seattle…
## 4 Fri   Nov 24, 2023 3:00        ""    Miami Dolphi… W 34… W -9.5 "@"   New Yor…
## 5 Sun   Nov 26, 2023 1:00        ""    New Orleans … L 15… L -1.5 "@"   Atlanta…
## 6 Sun   Nov 26, 2023 1:00        ""    Pittsburgh S… W 16… W -2.5 "@"   Cincinn…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 19 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Nov 30, 2023 8:15        "@"   Dallas Cowbo… W 41… L -9.5 ""    Seattle…
## 2 Sun   Dec 3, 2023  1:00        "@"   Houston Texa… W 22… W -3.5 ""    Denver …
## 3 Sun   Dec 3, 2023  1:00        ""    Los Angeles … W 6-0 W -4.5 "@"   New Eng…
## 4 Sun   Dec 3, 2023  1:00        ""    Detroit Lions W 33… W -4   "@"   New Orl…
## 5 Sun   Dec 3, 2023  1:00        ""    Atlanta Falc… W 13… W -2   "@"   New Yor…
## 6 Sun   Dec 3, 2023  1:00        "@"   Pittsburgh S… L 10… L -6   ""    Arizona…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 20 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Dec 7, 2023  8:15        "@"   Pittsburgh S… L 18… L -5.5 ""    New Eng…
## 2 Sun   Dec 10, 2023 1:00        "@"   Atlanta Falc… L 25… L -1.5 ""    Tampa B…
## 3 Sun   Dec 10, 2023 1:00        "@"   Baltimore Ra… W 37… L -7.5 ""    Los Ang…
## 4 Sun   Dec 10, 2023 1:00        ""    Detroit Lions L 13… L -3   "@"   Chicago…
## 5 Sun   Dec 10, 2023 1:00        "@"   Cincinnati B… W 34… W -3   ""    Indiana…
## 6 Sun   Dec 10, 2023 1:00        "@"   Cleveland Br… W 31… W -2.5 ""    Jackson…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 21 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Dec 14, 2023 8:15        "@"   Las Vegas Ra… W 63… W -3   ""    Los Ang…
## 2 Sat   Dec 16, 2023 1:00        "@"   Cincinnati B… W 27… P -3   ""    Minneso…
## 3 Sat   Dec 16, 2023 4:30        "@"   Indianapolis… W 30… W -1.5 ""    Pittsbu…
## 4 Sat   Dec 16, 2023 8:15        "@"   Detroit Lions W 42… W -5.5 ""    Denver …
## 5 Sun   Dec 17, 2023 1:00        ""    Atlanta Falc… L 7-9 L -3   "@"   Carolin…
## 6 Sun   Dec 17, 2023 1:00        "@"   Cleveland Br… W 20… W -2.5 ""    Chicago…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 22 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Dec 21, 2023 8:15        "@"   Los Angeles … W 30… W -4   ""    New Orl…
## 2 Sat   Dec 23, 2023 4:30        ""    Cincinnati B… L 11… L -3   "@"   Pittsbu…
## 3 Sat   Dec 23, 2023 8:00        ""    Buffalo Bills W 24… L -12… "@"   Los Ang…
## 4 Sun   Dec 24, 2023 1:00        "@"   Atlanta Falc… W 29… W -2.5 ""    Indiana…
## 5 Sun   Dec 24, 2023 1:00        ""    Green Bay Pa… W 33… L -3.5 "@"   Carolin…
## 6 Sun   Dec 24, 2023 1:00        ""    Cleveland Br… W 36… W -3   "@"   Houston…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 23 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Dec 28, 2023 8:15        @     Cleveland Br… W 37… W -7   ""    New Yor…
## 2 Sat   Dec 30, 2023 8:15        @     Dallas Cowbo… W 20… L -5   ""    Detroit…
## 3 Sun   Dec 31, 2023 1:00        @     Baltimore Ra… W 56… W -3.5 ""    Miami D…
## 4 Sun   Dec 31, 2023 1:00        @     Buffalo Bills W 27… L -14… ""    New Eng…
## 5 Sun   Dec 31, 2023 1:00        @     Chicago Bears W 37… W -2.5 ""    Atlanta…
## 6 Sun   Dec 31, 2023 1:00        @     Houston Texa… W 26… W -5.5 ""    Tenness…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 24 ---
## # A tibble: 6 × 12
##   Day   Date        `Time (ET)` ``    Favorite       Score Spread ``    Underdog
##   <chr> <chr>       <chr>       <chr> <chr>          <chr> <chr>  <chr> <chr>   
## 1 Sat   Jan 6, 2024 4:30        ""    Pittsburgh St… W 17… W -3   "@"   Baltimo…
## 2 Sat   Jan 6, 2024 8:15        ""    Houston Texans W 23… W -1.5 "@"   Indiana…
## 3 Sun   Jan 7, 2024 1:00        ""    Tampa Bay Buc… W 9-0 W -4   "@"   Carolin…
## 4 Sun   Jan 7, 2024 1:00        "@"   Cincinnati Be… W 31… W -7.5 ""    Clevela…
## 5 Sun   Jan 7, 2024 1:00        "@"   Detroit Lions  W 30… W -3.5 ""    Minneso…
## 6 Sun   Jan 7, 2024 1:00        "@"   New England P… L 3-… L -2   ""    New Yor…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 25 ---
## # A tibble: 6 × 11
##   Round        Day   Date  `Time (ET)` ``    `Favorite(Seed)` Score Spread ``   
##   <chr>        <chr> <chr> <chr>       <chr> <chr>            <chr> <chr>  <chr>
## 1 AFC Wild Ca… Sat   Jan … 4:30        ""    Cleveland Brown… L 14… L -2   "@"  
## 2 AFC Wild Ca… Sat   Jan … 8:10        "@"   Kansas City Chi… W 26… W -4.5 ""   
## 3 NFC Wild Ca… Sun   Jan … 4:30        "@"   Dallas Cowboys … L 32… L -7   ""   
## 4 NFC Wild Ca… Sun   Jan … 8:15        "@"   Detroit Lions (… W 24… L -3   ""   
## 5 AFC Wild Ca… Mon   Jan … 4:30        "@"   Buffalo Bills (… W 31… W -10  ""   
## 6 NFC Wild Ca… Mon   Jan … 8:15        ""    Philadelphia Ea… L 9-… L -2.5 "@"  
## # ℹ 2 more variables: `Underdog(Seed)` <chr>, `Over/Under` <chr>
## 
## --- Table 26 ---
## # A tibble: 1 × 1
##   X1                                                                            
##   <chr>                                                                         
## 1 "Historical odds/data on this site are believed to be accurate.  Please let u…
# Loop through tables 6 to 19 and print their content
for (i in 6:19) {
  cat("\n--- Table", i, "---\n")
  table <- all_tables[[i]] %>% html_table(fill = TRUE)
  print(head(table))  # Print the first few rows of the table
}
## 
## --- Table 6 ---
## # A tibble: 6 × 3,345
##   X1     X2    X3    X4    X5    X6    X7    X8    X9    X10   X11   X12   X13  
##   <chr>  <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 "Back… Day   Date  "Tim… ""    Favo… Score "Spr… ""    Unde… "Ove… "Not… Thu  
## 2 "Day"  Date  Time… ""    "Fav… Score Spre… ""    "Und… Over… "Not… "Not… <NA> 
## 3 "Thu"  Sep … 8:20  "@"   "Kan… L 20… L -4  ""    "Det… U 53… "Not… ""    <NA> 
## 4 "Sun"  Sep … 1:00  "@"   "Atl… W 24… W -3  ""    "Car… U 43  ""     <NA> <NA> 
## 5 "Sun"  Sep … 1:00  "@"   "Bal… W 25… W -9  ""    "Hou… U 44… ""     <NA> <NA> 
## 6 "Sun"  Sep … 1:00  "@"   "Chi… L 20… L -2… ""    "Gre… O 44… ""     <NA> <NA> 
## # ℹ 3,332 more variables: X14 <chr>, X15 <chr>, X16 <chr>, X17 <chr>,
## #   X18 <chr>, X19 <chr>, X20 <lgl>, X21 <chr>, X22 <chr>, X23 <lgl>,
## #   X24 <chr>, X25 <chr>, X26 <chr>, X27 <chr>, X28 <chr>, X29 <chr>,
## #   X30 <chr>, X31 <lgl>, X32 <chr>, X33 <chr>, X34 <lgl>, X35 <chr>,
## #   X36 <chr>, X37 <chr>, X38 <chr>, X39 <chr>, X40 <chr>, X41 <chr>,
## #   X42 <lgl>, X43 <chr>, X44 <chr>, X45 <lgl>, X46 <chr>, X47 <chr>,
## #   X48 <chr>, X49 <chr>, X50 <chr>, X51 <chr>, X52 <chr>, X53 <lgl>, …
## 
## --- Table 7 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Sep 7, 2023  8:20        "@"   Kansas City … L 20… L -4   ""    Detroit…
## 2 Sun   Sep 10, 2023 1:00        "@"   Atlanta Falc… W 24… W -3   ""    Carolin…
## 3 Sun   Sep 10, 2023 1:00        "@"   Baltimore Ra… W 25… W -9   ""    Houston…
## 4 Sun   Sep 10, 2023 1:00        "@"   Chicago Bears L 20… L -2.5 ""    Green B…
## 5 Sun   Sep 10, 2023 1:00        ""    Cincinnati B… L 3-… L -1   "@"   Clevela…
## 6 Sun   Sep 10, 2023 1:00        ""    Jacksonville… W 31… W -3.5 "@"   Indiana…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 8 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Sep 14, 2023 8:15        @     Philadelphia… W 34… P -6   ""    Minneso…
## 2 Sun   Sep 17, 2023 1:00        @     Atlanta Falc… W 25… L -3   ""    Green B…
## 3 Sun   Sep 17, 2023 1:00        @     Buffalo Bills W 38… W -8   ""    Las Veg…
## 4 Sun   Sep 17, 2023 1:00        @     Cincinnati B… L 24… L -3.5 ""    Baltimo…
## 5 Sun   Sep 17, 2023 1:00        @     Detroit Lions L 31… L -4.5 ""    Seattle…
## 6 Sun   Sep 17, 2023 1:00        @     Houston Texa… L 20… L -1   ""    Indiana…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 9 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Sep 21, 2023 8:15        @     San Francisc… W 30… W -10… ""    New Yor…
## 2 Sun   Sep 24, 2023 1:00        @     Baltimore Ra… L 19… L -7.5 ""    Indiana…
## 3 Sun   Sep 24, 2023 1:00        @     Cleveland Br… W 27… W -3.5 ""    Tenness…
## 4 Sun   Sep 24, 2023 1:00        @     Detroit Lions W 20… W -3   ""    Atlanta…
## 5 Sun   Sep 24, 2023 1:00        @     Green Bay Pa… W 18… L -1.5 ""    New Orl…
## 6 Sun   Sep 24, 2023 1:00        @     Jacksonville… L 17… L -9.5 ""    Houston…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 10 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Sep 28, 2023 8:15        ""    Detroit Lions W 34… W -2.5 "@"   Green B…
## 2 Sun   Oct 1, 2023  9:30        "N"   Jacksonville… W 23… W -3.5 ""    Atlanta…
## 3 Sun   Oct 1, 2023  1:00        "@"   Buffalo Bills W 48… W -2.5 ""    Miami D…
## 4 Sun   Oct 1, 2023  1:00        ""    Minnesota Vi… W 21… W -4.5 "@"   Carolin…
## 5 Sun   Oct 1, 2023  1:00        ""    Denver Bronc… W 31… P -3   "@"   Chicago…
## 6 Sun   Oct 1, 2023  1:00        ""    Baltimore Ra… W 28… W -2.5 "@"   Clevela…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 11 ---
## # A tibble: 6 × 12
##   Day   Date        `Time (ET)` ``    Favorite       Score Spread ``    Underdog
##   <chr> <chr>       <chr>       <chr> <chr>          <chr> <chr>  <chr> <chr>   
## 1 Thu   Oct 5, 2023 8:15        "@"   Washington Co… L 20… L -6   ""    Chicago…
## 2 Sun   Oct 8, 2023 9:30        "N"   Buffalo Bills  L 20… L -5.5 ""    Jackson…
## 3 Sun   Oct 8, 2023 1:00        "@"   Atlanta Falco… W 21… L -2.5 ""    Houston…
## 4 Sun   Oct 8, 2023 1:00        "@"   Detroit Lions  W 42… W -9.5 ""    Carolin…
## 5 Sun   Oct 8, 2023 1:00        ""    Tennessee Tit… L 16… L -2.5 "@"   Indiana…
## 6 Sun   Oct 8, 2023 1:00        "@"   Miami Dolphins W 31… W -13  ""    New Yor…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 12 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Oct 12, 2023 8:15        "@"   Kansas City … W 19… W -10… ""    Denver …
## 2 Sun   Oct 15, 2023 9:30        "N"   Baltimore Ra… W 24… W -5   ""    Tenness…
## 3 Sun   Oct 15, 2023 1:00        "@"   Atlanta Falc… L 16… L -1.5 ""    Washing…
## 4 Sun   Oct 15, 2023 1:00        ""    Minnesota Vi… W 19… W -3   "@"   Chicago…
## 5 Sun   Oct 15, 2023 1:00        "@"   Cincinnati B… W 17… W -3   ""    Seattle…
## 6 Sun   Oct 15, 2023 1:00        ""    San Francisc… L 17… L -9.5 "@"   Clevela…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 13 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Oct 19, 2023 8:15        "@"   New Orleans … L 24… L -2.5 ""    Jackson…
## 2 Sun   Oct 22, 2023 1:00        "@"   Baltimore Ra… W 38… W -3   ""    Detroit…
## 3 Sun   Oct 22, 2023 1:00        ""    Las Vegas Ra… L 12… L -2.5 "@"   Chicago…
## 4 Sun   Oct 22, 2023 1:00        ""    Cleveland Br… W 39… L -3.5 "@"   Indiana…
## 5 Sun   Oct 22, 2023 1:00        ""    Buffalo Bills L 25… L -7.5 "@"   New Eng…
## 6 Sun   Oct 22, 2023 1:00        ""    Washington C… L 7-… L -3   "@"   New Yor…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 14 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Oct 26, 2023 8:15        "@"   Buffalo Bills W 24… L -10  ""    Tampa B…
## 2 Sun   Oct 29, 2023 1:00        ""    Houston Texa… L 13… L -3.5 "@"   Carolin…
## 3 Sun   Oct 29, 2023 1:00        "@"   Dallas Cowbo… W 43… W -6.5 ""    Los Ang…
## 4 Sun   Oct 29, 2023 1:00        ""    Minnesota Vi… W 24… W -1.5 "@"   Green B…
## 5 Sun   Oct 29, 2023 1:00        ""    New Orleans … W 38… W -1.5 "@"   Indiana…
## 6 Sun   Oct 29, 2023 1:00        "@"   Miami Dolphi… W 31… W -8.5 ""    New Eng…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 15 ---
## # A tibble: 6 × 12
##   Day   Date        `Time (ET)` ``    Favorite       Score Spread ``    Underdog
##   <chr> <chr>       <chr>       <chr> <chr>          <chr> <chr>  <chr> <chr>   
## 1 Thu   Nov 2, 2023 8:15        @     Pittsburgh St… W 20… W -3   ""    Tenness…
## 2 Sun   Nov 5, 2023 9:30        N     Kansas City C… W 21… W -1.5 ""    Miami D…
## 3 Sun   Nov 5, 2023 1:00        @     Atlanta Falco… L 28… L -3.5 ""    Minneso…
## 4 Sun   Nov 5, 2023 1:00        @     Baltimore Rav… W 37… W -6.5 ""    Seattle…
## 5 Sun   Nov 5, 2023 1:00        @     Cleveland Bro… W 27… W -13… ""    Arizona…
## 6 Sun   Nov 5, 2023 1:00        @     Green Bay Pac… W 20… W -3.5 ""    Los Ang…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 16 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Nov 9, 2023  8:15        "@"   Chicago Bears W 16… L -3.5 ""    Carolin…
## 2 Sun   Nov 12, 2023 9:30        "N"   Indianapolis… W 10… W -2.5 ""    New Eng…
## 3 Sun   Nov 12, 2023 1:00        "@"   Baltimore Ra… L 31… L -6   ""    Clevela…
## 4 Sun   Nov 12, 2023 1:00        "@"   Cincinnati B… L 27… L -5.5 ""    Houston…
## 5 Sun   Nov 12, 2023 1:00        ""    San Francisc… W 34… W -3   "@"   Jackson…
## 6 Sun   Nov 12, 2023 1:00        ""    New Orleans … L 19… L -2.5 "@"   Minneso…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 17 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Nov 16, 2023 8:15        "@"   Baltimore Ra… W 34… W -3.5 ""    Cincinn…
## 2 Sun   Nov 19, 2023 1:00        ""    Dallas Cowbo… W 33… W -11  "@"   Carolin…
## 3 Sun   Nov 19, 2023 1:00        "@"   Cleveland Br… W 13… W -1.5 ""    Pittsbu…
## 4 Sun   Nov 19, 2023 1:00        "@"   Detroit Lions W 31… L -7.5 ""    Chicago…
## 5 Sun   Nov 19, 2023 1:00        ""    Los Angeles … L 20… L -3   "@"   Green B…
## 6 Sun   Nov 19, 2023 1:00        "@"   Houston Texa… W 21… L -5.5 ""    Arizona…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 18 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Nov 23, 2023 12:30       "@"   Detroit Lions L 22… L -8.5 ""    Green B…
## 2 Thu   Nov 23, 2023 4:30        "@"   Dallas Cowbo… W 45… W -13… ""    Washing…
## 3 Thu   Nov 23, 2023 8:20        ""    San Francisc… W 31… W -7   "@"   Seattle…
## 4 Fri   Nov 24, 2023 3:00        ""    Miami Dolphi… W 34… W -9.5 "@"   New Yor…
## 5 Sun   Nov 26, 2023 1:00        ""    New Orleans … L 15… L -1.5 "@"   Atlanta…
## 6 Sun   Nov 26, 2023 1:00        ""    Pittsburgh S… W 16… W -2.5 "@"   Cincinn…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
## 
## --- Table 19 ---
## # A tibble: 6 × 12
##   Day   Date         `Time (ET)` ``    Favorite      Score Spread ``    Underdog
##   <chr> <chr>        <chr>       <chr> <chr>         <chr> <chr>  <chr> <chr>   
## 1 Thu   Nov 30, 2023 8:15        "@"   Dallas Cowbo… W 41… L -9.5 ""    Seattle…
## 2 Sun   Dec 3, 2023  1:00        "@"   Houston Texa… W 22… W -3.5 ""    Denver …
## 3 Sun   Dec 3, 2023  1:00        ""    Los Angeles … W 6-0 W -4.5 "@"   New Eng…
## 4 Sun   Dec 3, 2023  1:00        ""    Detroit Lions W 33… W -4   "@"   New Orl…
## 5 Sun   Dec 3, 2023  1:00        ""    Atlanta Falc… W 13… W -2   "@"   New Yor…
## 6 Sun   Dec 3, 2023  1:00        "@"   Pittsburgh S… L 10… L -6   ""    Arizona…
## # ℹ 3 more variables: `Over/Under` <chr>, Notes <chr>, `` <chr>
# Check if table contains the correct columns
game_table <- all_tables[[6]] %>% 
  html_table(fill = TRUE) %>%
  as_tibble()
# Cleans column titles scraped data table
game_table_cleaned <- game_table %>%
  select(
    Day = X1,             
    Date = X2,              
    Time = X3,             
    Home_Away = X4,       
    Favorite = X5,          
    Score = X6,             
    Spread = X7,          
    Underdog_Home_Away = X8, 
    Underdog = X9,         
    Over_Under = X10     
  )
 # Remove rows where key columns contain header titles
game_table_cleaned <- game_table_cleaned %>%
  filter(
    !(Day == "Day" | Date == "Date" | Favorite == "Favorite") 
  )
# Retain only columns with non-NA values
game_table_cleaned <- game_table_cleaned %>%
  select(where(~ any(!is.na(.))))  
# Cleans Spread column
game_table_cleaned <- game_table_cleaned %>%
  filter(grepl("^[WL] -?\\d+(\\.\\d+)?$", Spread))
 # Removes W or L and converts to numeric
game_table_cleaned <- game_table_cleaned %>%
  mutate(
    Spread = as.numeric(gsub("^[WL] ", "", Spread))  # Remove `W ` or `L ` and convert to numeric
  )
game_table_cleaned <- game_table_cleaned %>%
  rename(
    Favorite_Location = Home_Away,
    Underdog_Location = Underdog_Home_Away
  )
game_table_cleaned <- game_table_cleaned %>%
  mutate(
    Favorite_Location = ifelse(Favorite_Location == "@", "away", "home"), 
    Underdog_Location = ifelse(Underdog_Location == "@", "away", "home")  
  )
game_table_cleaned <- game_table_cleaned %>%
  mutate(Date = lubridate::mdy(Date))
game_table_cleaned <- game_table_cleaned %>%
  separate(Score, into = c("Result", "Scores"), sep = " ") %>%
  separate(Scores, into = c("Favorite_Score", "Underdog_Score"), sep = "-") %>%
  mutate(
    Favorite_Score = as.numeric(Favorite_Score),
    Underdog_Score = as.numeric(Underdog_Score)
  )
## Warning: Expected 2 pieces. Additional pieces discarded in 12 rows [16, 20, 24, 32, 52,
## 54, 109, 174, 183, 189, 192, 212].
game_table_cleaned <- game_table_cleaned %>%
  mutate(
    Over_Under = as.numeric(gsub("[UO] ", "", Over_Under))
  )
win_rate <- game_table_cleaned %>%
  group_by(Favorite_Location) %>%
  summarise(Favorite_Win_Rate = mean(Result == "W"), .groups = "drop")

print(win_rate)
## # A tibble: 2 × 2
##   Favorite_Location Favorite_Win_Rate
##   <chr>                         <dbl>
## 1 away                          0.685
## 2 home                          0.647

This code calculates the win rate of teams designated as the favorite based on their location, whether playing at home or away. It groups the cleaned game data by Favorite_Location and calculates the mean win rate (Result == “W”) for each group. The results show that favorites playing away have a slightly higher win rate (68.52%) compared to those playing at home (64.71%). As expected, this suggests that being labeled as the favorite may be a greater advantage overall then homefield advantage.

library(ggplot2)

# Spread distribution
ggplot(game_table_cleaned, aes(x = Spread)) +
  geom_histogram(binwidth = 1, fill = "blue", color = "black") +
  labs(title = "Distribution of Spread Values", x = "Spread", y = "Frequency")

This code creates a histogram to visualize the distribution of spread values from the cleaned game data. The x-axis represents the spread, which is the predicted margin of victory for the favored team, while the y-axis shows the frequency of games within each spread range. The histogram reveals that most spreads are concentrated around -5, indicating that favorites were commonly predicted to win by around 0 to 5 points. The distribution also shows fewer extreme spreads, such as values below -10 or near 0, suggesting those predictions are less common. This visualization helps identify patterns in how games were expected to play out.

spread_analysis <- game_table_cleaned %>%
  summarise(
    Avg_Spread = mean(Spread, na.rm = TRUE),
    Home_Spread = mean(Spread[Favorite_Location == "home"], na.rm = TRUE),
    Away_Spread = mean(Spread[Favorite_Location == "away"], na.rm = TRUE)
  )
print(spread_analysis)
## # A tibble: 1 × 3
##   Avg_Spread Home_Spread Away_Spread
##        <dbl>       <dbl>       <dbl>
## 1      -4.95       -4.24       -5.40

This code calculates the average spread across all games, as well as separately for games where the favorite team played at home versus away. The overall average spread is approximately -4.95, indicating that favored teams were generally expected to win by nearly 5 points. When the favorite team played at home, the average spread was slightly smaller (-4.24), compared to games where the favorite played away (-5.39). Unexpectedly this suggests that home teams were typically given a smaller margin of victory compared to away teams.

over_under_analysis <- game_table_cleaned %>%
  summarise(
    Over_Count = sum(Result == "W" & Over_Under > Favorite_Score + Underdog_Score),
    Under_Count = sum(Result == "L" & Over_Under < Favorite_Score + Underdog_Score)
  )
print(over_under_analysis)
## # A tibble: 1 × 2
##   Over_Count Under_Count
##        <int>       <int>
## 1         97          41

This code calculates the number of games where the total points scored exceeded or fell short of the projected “over/under” value. The results show that 97 games went “over,” meaning the actual combined score was greater than the predicted total, while 41 games went “under,” where the total score was less than the prediction. Over two thirds of the games ended over the projected total, a significant portion for a form of betting odds that is intended to be split 50/50 for each side.

game_table_cleaned <- game_table_cleaned %>%
  mutate(Result = ifelse(Result == "W", 1, 0))

glm_model <- glm(Result ~ Spread + Favorite_Location + Over_Under,
                 data = game_table_cleaned, family = binomial)
summary(glm_model)
## 
## Call:
## glm(formula = Result ~ Spread + Favorite_Location + Over_Under, 
##     family = binomial, data = game_table_cleaned)
## 
## Coefficients:
##                       Estimate Std. Error z value Pr(>|z|)  
## (Intercept)           -2.36010    1.29621  -1.821   0.0686 .
## Spread                -0.07542    0.04340  -1.738   0.0822 .
## Favorite_Locationhome -0.09024    0.27491  -0.328   0.7427  
## Over_Under             0.06429    0.03024   2.126   0.0335 *
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 334.68  on 263  degrees of freedom
## Residual deviance: 325.54  on 260  degrees of freedom
## AIC: 333.54
## 
## Number of Fisher Scoring iterations: 4

This code uses a logistic regression model to find the likelihood of a team winning based on the spread, the team’s location, and the over/under value. For the spread, it results in a negative coefficient of -.07542, which suggests that as the spread becomes more favorable for the expected winner, the probability of a win decreases slightly, however this result is not statistically significant due to a p value of .0822. Surprisingly, according to this model location has a negligible effect on outcomes of games, this can be seen through the p value of .7427. For the Over/Under, the coefficient of .06429 and p value of .0335 indicates that games with higher over/under values are slightly more likely to result in wins for the favorite.

lm_model <- lm(Spread ~ Favorite_Score + Underdog_Score + Favorite_Location,
               data = game_table_cleaned)

summary(lm_model)
## 
## Call:
## lm(formula = Spread ~ Favorite_Score + Underdog_Score + Favorite_Location, 
##     data = game_table_cleaned)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -10.989  -1.450   1.030   2.294   5.505 
## 
## Coefficients:
##                       Estimate Std. Error t value Pr(>|t|)    
## (Intercept)           -3.45272    0.73547  -4.695 4.33e-06 ***
## Favorite_Score        -0.08512    0.02007  -4.241 3.10e-05 ***
## Underdog_Score         0.01478    0.02292   0.645   0.5195    
## Favorite_Locationhome  0.86449    0.42344   2.042   0.0422 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 3.299 on 260 degrees of freedom
## Multiple R-squared:  0.09137,    Adjusted R-squared:  0.08089 
## F-statistic: 8.715 on 3 and 260 DF,  p-value: 1.574e-05

This code uses a linear regression model to utilize the spread as a function of the favorite team’s score, the underdog team’s score, and the favorite team’s location. The baseline spread is -3.45, indicating that on average the favorite team is projected to win by 3.45 points when all other variables are at their baseline levels. For Favorite_Score, The coefficient of -.08512 indicates that for every additional point scored by the favorite team, the spread decreases slightly. The coefficient for the Underdog_score (.5195) is not statistically significant and implicates that the underdog score has little or no effect at all on the spread. For Favorite_Locationhome, the coefficient of .86449 indicates that when the favorite team is at home, the spread increases slightly, implying that their is a home-field advantage in the eyes of the odds makers.

exp(coef(glm_model))
##           (Intercept)                Spread Favorite_Locationhome 
##            0.09441031            0.92735822            0.91371001 
##            Over_Under 
##            1.06640559
library(broom)
augment(glm_model)
## # A tibble: 264 × 10
##    Result Spread Favorite_Location Over_Under .fitted .resid    .hat .sigma
##     <dbl>  <dbl> <chr>                  <dbl>   <dbl>  <dbl>   <dbl>  <dbl>
##  1      0   -4   away                    53.5   1.38  -1.79  0.0231    1.12
##  2      1   -3   away                    43     0.631  0.924 0.00846   1.12
##  3      1   -9   away                    44.5   1.18   0.732 0.0112    1.12
##  4      0   -2.5 away                    44.5   0.690 -1.48  0.0102    1.12
##  5      0   -1   home                    46.5   0.615 -1.45  0.0178    1.12
##  6      1   -3.5 home                    43.5   0.610  0.931 0.0104    1.12
##  7      0   -4   away                    45.5   0.867 -1.56  0.00838   1.12
##  8      1   -3.5 away                    41.5   0.572  0.946 0.00790   1.12
##  9      1   -2.5 home                    40.5   0.342  1.04  0.0125    1.12
## 10      1   -6   away                    40.5   0.696  0.899 0.00796   1.12
## # ℹ 254 more rows
## # ℹ 2 more variables: .cooksd <dbl>, .std.resid <dbl>
library(ggplot2)
ggplot(game_table_cleaned, aes(x = Spread, y = fitted(glm_model))) +
  geom_point() +
  geom_smooth(method = "glm", method.args = list(family = "binomial"), se = TRUE)
## `geom_smooth()` using formula = 'y ~ x'
## Warning in eval(family$initialize): non-integer #successes in a binomial glm!

This plot visualizes the relationship between the spread and the predicted probability of the favorite team winning, as calculated by the logistic regression model “glm_model”. This plot shows that as the spread approaches 0, the predicted probability of the favorite team winning decreases. This aligns with what was seen earlier in regards to a smaller spread reflecting a less dominant favorite.

library(httr)
library(dplyr)
library(jsonlite)
## 
## Attaching package: 'jsonlite'
## The following object is masked from 'package:purrr':
## 
##     flatten
library(purrr)

# Define API key and base URL
api_key <- api_key
events_url <- "https://api.the-odds-api.com/v4/historical/sports/americanfootball_nfl/events"

# Specify the date for historical events
query_params <- list(
  apiKey = api_key,
  regions = "us",
  date = "2023-09-07T00:00:00Z"  # Replace with your desired date
)

# Send GET request
response <- GET(url = events_url, query = query_params)

# Check for successful response
if (status_code(response) == 200) {
  # Parse the raw response
  response_data <- content(response, as = "parsed", simplifyVector = TRUE)
  
  # Validate the structure of the response
  if (!is.null(response_data$data) && is.list(response_data$data)) {
    events_list <- response_data$data  # Assign valid data to events_list
    
    if (length(events_list) > 0) {
      # Extract relevant fields with map functions to handle missing keys safely
      events <- data.frame(
        event_id = map_chr(events_list, "id", .default = NA),
        sport_key = map_chr(events_list, "sport_key", .default = NA),
        sport_title = map_chr(events_list, "sport_title", .default = NA),
        commence_time = map_chr(events_list, "commence_time", .default = NA),
        home_team = map_chr(events_list, "home_team", .default = NA),
        away_team = map_chr(events_list, "away_team", .default = NA)
      )
      
      # Print the first few rows of the extracted data
      print(head(events))
    } else {
      print("The events list is empty.")
    }
  } else {
    print("No valid events found in the response.")
  }
} else {
  print(paste("Error fetching events:", status_code(response)))
}
##               event_id sport_key sport_title commence_time home_team away_team
## id                <NA>      <NA>        <NA>          <NA>      <NA>      <NA>
## sport_key         <NA>      <NA>        <NA>          <NA>      <NA>      <NA>
## sport_title       <NA>      <NA>        <NA>          <NA>      <NA>      <NA>
## commence_time     <NA>      <NA>        <NA>          <NA>      <NA>      <NA>
## home_team         <NA>      <NA>        <NA>          <NA>      <NA>      <NA>
## away_team         <NA>      <NA>        <NA>          <NA>      <NA>      <NA>
library(httr)
library(jsonlite)
library(dplyr)

# Subset the first 93 rows from events_list
limited_events <- events_list[1:93, ]

# Initialize an empty list to store the props data
player_props_list <- list()

for (i in seq_len(nrow(limited_events))) {
  event_id <- limited_events$id[i]
  
  # Construct the API endpoint
  url <- paste0("https://api.the-odds-api.com/v4/historical/sports/americanfootball_nfl/events/",
                event_id,
                "/odds")
  
  # Make the GET request
  response <- GET(
    url = url,
    query = list(
      apiKey = api_key,
      regions = "us",
      markets = "player_reception_yds",  # Market for player props
      date = limited_events$commence_time[i]
    )
  )
  
  # Check for successful response
  if (status_code(response) == 200) {
    content_data <- content(response, as = "parsed", simplifyVector = TRUE)
    
    # Extract player props if available
    if (!is.null(content_data$data) && !is.null(content_data$data$bookmakers)) {
      for (bookmaker in content_data$data$bookmakers) {
        # Debug: Print the structure of bookmaker if an issue arises
        if (!is.list(bookmaker)) {
          message("Invalid bookmaker format:")
          print(bookmaker)
          next
        }
        
        # Ensure markets exist and are a list
        if (!is.null(bookmaker$markets) && is.list(bookmaker$markets)) {
          for (market in bookmaker$markets) {
            if (!is.null(market$key) && market$key == "player_reception_yds") {
              # Parse player props data
              market_data <- map_dfr(market$outcomes, ~ {
                tibble(
                  player = .x$description,
                  over_under = .x$name,
                  point = .x$point,
                  price = .x$price,
                  event_id = event_id,
                  home_team = limited_events$home_team[i],
                  away_team = limited_events$away_team[i],
                  commence_time = limited_events$commence_time[i],
                  bookmaker = bookmaker$title
                )
              })
              
              # Append to the results list
              player_props_list <- append(player_props_list, list(market_data))
            }
          }
        } else {
          message("Skipping invalid or empty markets for bookmaker: ", bookmaker$title)
        }
      }
    }
  } else {
    message("Failed to fetch data for event ID: ", event_id)
  }
}
## Invalid bookmaker format:
##  [1] "fanduel"        "williamhill_us" "pointsbetus"    "betrivers"     
##  [5] "unibet_us"      "betonlineag"    "bovada"         "betmgm"        
##  [9] "draftkings"     "barstool"
## Invalid bookmaker format:
##  [1] "FanDuel"             "William Hill (US)"   "PointsBet (US)"     
##  [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
##  [7] "Bovada"              "BetMGM"              "DraftKings"         
## [10] "Barstool Sportsbook"
## Invalid bookmaker format:
##  [1] "2023-09-08T00:15:19Z" "2023-09-08T00:15:06Z" "2023-09-08T00:15:09Z"
##  [4] "2023-09-08T00:14:58Z" "2023-09-08T00:15:19Z" "2023-09-08T00:15:31Z"
##  [7] "2023-09-08T00:15:19Z" "2023-09-08T00:15:34Z" "2023-09-08T00:15:22Z"
## [10] "2023-09-08T00:15:28Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "fanduel"        "williamhill_us" "pointsbetus"    "betrivers"     
##  [5] "unibet_us"      "betonlineag"    "bovada"         "betmgm"        
##  [9] "draftkings"     "barstool"
## Invalid bookmaker format:
##  [1] "FanDuel"             "William Hill (US)"   "PointsBet (US)"     
##  [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
##  [7] "Bovada"              "BetMGM"              "DraftKings"         
## [10] "Barstool Sportsbook"
## Invalid bookmaker format:
##  [1] "2023-09-10T16:55:14Z" "2023-09-10T16:55:22Z" "2023-09-10T16:55:13Z"
##  [4] "2023-09-10T16:55:24Z" "2023-09-10T16:54:51Z" "2023-09-10T16:54:58Z"
##  [7] "2023-09-10T16:54:58Z" "2023-09-10T16:55:07Z" "2023-09-10T16:55:30Z"
## [10] "2023-09-10T16:54:52Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "fanduel"        "williamhill_us" "pointsbetus"    "betrivers"     
##  [5] "unibet_us"      "betonlineag"    "bovada"         "betmgm"        
##  [9] "draftkings"     "barstool"
## Invalid bookmaker format:
##  [1] "FanDuel"             "William Hill (US)"   "PointsBet (US)"     
##  [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
##  [7] "Bovada"              "BetMGM"              "DraftKings"         
## [10] "Barstool Sportsbook"
## Invalid bookmaker format:
##  [1] "2023-09-10T16:55:14Z" "2023-09-10T16:55:22Z" "2023-09-10T16:55:13Z"
##  [4] "2023-09-10T16:55:24Z" "2023-09-10T16:54:51Z" "2023-09-10T16:54:58Z"
##  [7] "2023-09-10T16:54:58Z" "2023-09-10T16:55:07Z" "2023-09-10T16:55:30Z"
## [10] "2023-09-10T16:54:52Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "fanduel"        "williamhill_us" "pointsbetus"    "betrivers"     
##  [5] "unibet_us"      "betonlineag"    "bovada"         "betmgm"        
##  [9] "draftkings"     "barstool"
## Invalid bookmaker format:
##  [1] "FanDuel"             "William Hill (US)"   "PointsBet (US)"     
##  [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
##  [7] "Bovada"              "BetMGM"              "DraftKings"         
## [10] "Barstool Sportsbook"
## Invalid bookmaker format:
##  [1] "2023-09-10T16:55:14Z" "2023-09-10T16:55:22Z" "2023-09-10T16:55:13Z"
##  [4] "2023-09-10T16:55:24Z" "2023-09-10T16:54:51Z" "2023-09-10T16:54:58Z"
##  [7] "2023-09-10T16:54:58Z" "2023-09-10T16:55:07Z" "2023-09-10T16:55:30Z"
## [10] "2023-09-10T16:54:52Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
## [1] "fanduel"        "williamhill_us" "pointsbetus"    "betrivers"     
## [5] "unibet_us"      "betonlineag"    "bovada"         "draftkings"    
## [9] "barstool"
## Invalid bookmaker format:
## [1] "FanDuel"             "William Hill (US)"   "PointsBet (US)"     
## [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
## [7] "Bovada"              "DraftKings"          "Barstool Sportsbook"
## Invalid bookmaker format:
## [1] "2023-09-10T16:55:14Z" "2023-09-10T16:55:22Z" "2023-09-10T16:55:13Z"
## [4] "2023-09-10T16:55:24Z" "2023-09-10T16:54:51Z" "2023-09-10T16:54:58Z"
## [7] "2023-09-10T16:54:58Z" "2023-09-10T16:55:30Z" "2023-09-10T16:54:52Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "fanduel"        "williamhill_us" "pointsbetus"    "betrivers"     
##  [5] "unibet_us"      "betonlineag"    "bovada"         "betmgm"        
##  [9] "draftkings"     "barstool"
## Invalid bookmaker format:
##  [1] "FanDuel"             "William Hill (US)"   "PointsBet (US)"     
##  [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
##  [7] "Bovada"              "BetMGM"              "DraftKings"         
## [10] "Barstool Sportsbook"
## Invalid bookmaker format:
##  [1] "2023-09-10T16:55:14Z" "2023-09-10T16:55:22Z" "2023-09-10T16:55:13Z"
##  [4] "2023-09-10T16:55:24Z" "2023-09-10T16:54:51Z" "2023-09-10T16:54:58Z"
##  [7] "2023-09-10T16:54:58Z" "2023-09-10T16:55:07Z" "2023-09-10T16:55:30Z"
## [10] "2023-09-10T16:54:52Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "fanduel"        "williamhill_us" "pointsbetus"    "betrivers"     
##  [5] "unibet_us"      "betonlineag"    "bovada"         "betmgm"        
##  [9] "draftkings"     "barstool"
## Invalid bookmaker format:
##  [1] "FanDuel"             "William Hill (US)"   "PointsBet (US)"     
##  [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
##  [7] "Bovada"              "BetMGM"              "DraftKings"         
## [10] "Barstool Sportsbook"
## Invalid bookmaker format:
##  [1] "2023-09-10T16:55:14Z" "2023-09-10T16:55:22Z" "2023-09-10T16:55:13Z"
##  [4] "2023-09-10T16:55:24Z" "2023-09-10T16:54:51Z" "2023-09-10T16:54:58Z"
##  [7] "2023-09-10T16:54:58Z" "2023-09-10T16:55:07Z" "2023-09-10T16:55:30Z"
## [10] "2023-09-10T16:54:52Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "fanduel"        "williamhill_us" "pointsbetus"    "betrivers"     
##  [5] "unibet_us"      "betonlineag"    "bovada"         "betmgm"        
##  [9] "draftkings"     "barstool"
## Invalid bookmaker format:
##  [1] "FanDuel"             "William Hill (US)"   "PointsBet (US)"     
##  [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
##  [7] "Bovada"              "BetMGM"              "DraftKings"         
## [10] "Barstool Sportsbook"
## Invalid bookmaker format:
##  [1] "2023-09-10T16:55:14Z" "2023-09-10T16:55:22Z" "2023-09-10T16:55:13Z"
##  [4] "2023-09-10T16:55:24Z" "2023-09-10T16:54:51Z" "2023-09-10T16:54:58Z"
##  [7] "2023-09-10T16:54:58Z" "2023-09-10T16:55:07Z" "2023-09-10T16:55:30Z"
## [10] "2023-09-10T16:54:52Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "fanduel"        "williamhill_us" "pointsbetus"    "betrivers"     
##  [5] "unibet_us"      "betonlineag"    "bovada"         "betmgm"        
##  [9] "draftkings"     "barstool"
## Invalid bookmaker format:
##  [1] "FanDuel"             "William Hill (US)"   "PointsBet (US)"     
##  [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
##  [7] "Bovada"              "BetMGM"              "DraftKings"         
## [10] "Barstool Sportsbook"
## Invalid bookmaker format:
##  [1] "2023-09-10T16:55:14Z" "2023-09-10T16:55:22Z" "2023-09-10T16:55:13Z"
##  [4] "2023-09-10T16:55:24Z" "2023-09-10T16:54:51Z" "2023-09-10T16:54:58Z"
##  [7] "2023-09-10T16:54:58Z" "2023-09-10T16:55:07Z" "2023-09-10T16:55:30Z"
## [10] "2023-09-10T16:54:52Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "fanduel"        "williamhill_us" "pointsbetus"    "betrivers"     
##  [5] "unibet_us"      "betonlineag"    "bovada"         "betmgm"        
##  [9] "draftkings"     "barstool"
## Invalid bookmaker format:
##  [1] "FanDuel"             "William Hill (US)"   "PointsBet (US)"     
##  [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
##  [7] "Bovada"              "BetMGM"              "DraftKings"         
## [10] "Barstool Sportsbook"
## Invalid bookmaker format:
##  [1] "2023-09-10T20:20:32Z" "2023-09-10T20:20:05Z" "2023-09-10T20:20:13Z"
##  [4] "2023-09-10T20:19:48Z" "2023-09-10T20:20:05Z" "2023-09-10T20:20:13Z"
##  [7] "2023-09-10T20:20:22Z" "2023-09-10T20:19:39Z" "2023-09-10T20:20:13Z"
## [10] "2023-09-10T20:20:33Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "fanduel"        "williamhill_us" "pointsbetus"    "betrivers"     
##  [5] "unibet_us"      "betonlineag"    "bovada"         "betmgm"        
##  [9] "draftkings"     "barstool"
## Invalid bookmaker format:
##  [1] "FanDuel"             "William Hill (US)"   "PointsBet (US)"     
##  [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
##  [7] "Bovada"              "BetMGM"              "DraftKings"         
## [10] "Barstool Sportsbook"
## Invalid bookmaker format:
##  [1] "2023-09-10T20:20:32Z" "2023-09-10T20:20:05Z" "2023-09-10T20:20:13Z"
##  [4] "2023-09-10T20:20:32Z" "2023-09-10T20:20:05Z" "2023-09-10T20:20:13Z"
##  [7] "2023-09-10T20:20:22Z" "2023-09-10T20:19:39Z" "2023-09-10T20:20:13Z"
## [10] "2023-09-10T20:20:33Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "fanduel"        "williamhill_us" "pointsbetus"    "betrivers"     
##  [5] "unibet_us"      "betonlineag"    "bovada"         "betmgm"        
##  [9] "draftkings"     "barstool"
## Invalid bookmaker format:
##  [1] "FanDuel"             "William Hill (US)"   "PointsBet (US)"     
##  [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
##  [7] "Bovada"              "BetMGM"              "DraftKings"         
## [10] "Barstool Sportsbook"
## Invalid bookmaker format:
##  [1] "2023-09-10T20:20:32Z" "2023-09-10T20:20:05Z" "2023-09-10T20:20:13Z"
##  [4] "2023-09-10T20:20:32Z" "2023-09-10T20:20:05Z" "2023-09-10T20:20:13Z"
##  [7] "2023-09-10T20:20:22Z" "2023-09-10T20:19:39Z" "2023-09-10T20:20:13Z"
## [10] "2023-09-10T20:20:33Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "fanduel"        "williamhill_us" "pointsbetus"    "betrivers"     
##  [5] "unibet_us"      "betonlineag"    "bovada"         "betmgm"        
##  [9] "draftkings"     "barstool"
## Invalid bookmaker format:
##  [1] "FanDuel"             "William Hill (US)"   "PointsBet (US)"     
##  [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
##  [7] "Bovada"              "BetMGM"              "DraftKings"         
## [10] "Barstool Sportsbook"
## Invalid bookmaker format:
##  [1] "2023-09-10T20:20:32Z" "2023-09-10T20:20:05Z" "2023-09-10T20:20:13Z"
##  [4] "2023-09-10T20:20:32Z" "2023-09-10T20:20:05Z" "2023-09-10T20:20:13Z"
##  [7] "2023-09-10T20:20:22Z" "2023-09-10T20:19:39Z" "2023-09-10T20:20:13Z"
## [10] "2023-09-10T20:20:33Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "fanduel"        "williamhill_us" "pointsbetus"    "betrivers"     
##  [5] "unibet_us"      "betonlineag"    "bovada"         "betmgm"        
##  [9] "draftkings"     "barstool"
## Invalid bookmaker format:
##  [1] "FanDuel"             "William Hill (US)"   "PointsBet (US)"     
##  [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
##  [7] "Bovada"              "BetMGM"              "DraftKings"         
## [10] "Barstool Sportsbook"
## Invalid bookmaker format:
##  [1] "2023-09-10T20:20:32Z" "2023-09-10T20:20:05Z" "2023-09-10T20:20:13Z"
##  [4] "2023-09-10T20:20:32Z" "2023-09-10T20:20:05Z" "2023-09-10T20:20:13Z"
##  [7] "2023-09-10T20:20:22Z" "2023-09-10T20:19:39Z" "2023-09-10T20:20:13Z"
## [10] "2023-09-10T20:20:33Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "fanduel"        "williamhill_us" "pointsbetus"    "betrivers"     
##  [5] "unibet_us"      "betonlineag"    "bovada"         "betmgm"        
##  [9] "draftkings"     "barstool"
## Invalid bookmaker format:
##  [1] "FanDuel"             "William Hill (US)"   "PointsBet (US)"     
##  [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
##  [7] "Bovada"              "BetMGM"              "DraftKings"         
## [10] "Barstool Sportsbook"
## Invalid bookmaker format:
##  [1] "2023-09-11T00:15:26Z" "2023-09-11T00:15:21Z" "2023-09-11T00:15:15Z"
##  [4] "2023-09-11T00:15:27Z" "2023-09-11T00:15:22Z" "2023-09-11T00:15:11Z"
##  [7] "2023-09-11T00:15:02Z" "2023-09-11T00:14:23Z" "2023-09-11T00:15:08Z"
## [10] "2023-09-11T00:15:35Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
## [1] "fanduel"        "williamhill_us" "pointsbetus"    "betrivers"     
## [5] "unibet_us"      "betonlineag"    "betmgm"         "draftkings"    
## [9] "barstool"
## Invalid bookmaker format:
## [1] "FanDuel"             "William Hill (US)"   "PointsBet (US)"     
## [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
## [7] "BetMGM"              "DraftKings"          "Barstool Sportsbook"
## Invalid bookmaker format:
## [1] "2023-09-12T00:10:05Z" "2023-09-12T00:10:04Z" "2023-09-12T00:10:03Z"
## [4] "2023-09-12T00:10:25Z" "2023-09-12T00:09:54Z" "2023-09-12T00:10:15Z"
## [7] "2023-09-12T00:09:42Z" "2023-09-12T00:10:32Z" "2023-09-12T00:10:25Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "draftkings"     "williamhill_us" "unibet_us"      "betrivers"     
##  [5] "betonlineag"    "fanduel"        "bovada"         "pointsbetus"   
##  [9] "barstool"       "betmgm"
## Invalid bookmaker format:
##  [1] "DraftKings"          "William Hill (US)"   "Unibet"             
##  [4] "BetRivers"           "BetOnline.ag"        "FanDuel"            
##  [7] "Bovada"              "PointsBet (US)"      "Barstool Sportsbook"
## [10] "BetMGM"
## Invalid bookmaker format:
##  [1] "2023-09-15T00:09:31Z" "2023-09-15T00:09:33Z" "2023-09-15T00:09:31Z"
##  [4] "2023-09-15T00:09:32Z" "2023-09-15T00:09:30Z" "2023-09-15T00:09:31Z"
##  [7] "2023-09-15T00:09:31Z" "2023-09-15T00:09:30Z" "2023-09-15T00:09:32Z"
## [10] "2023-09-15T00:08:38Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "draftkings"     "williamhill_us" "unibet_us"      "betrivers"     
##  [5] "fanduel"        "pointsbetus"    "betonlineag"    "betmgm"        
##  [9] "barstool"       "bovada"
## Invalid bookmaker format:
##  [1] "DraftKings"          "William Hill (US)"   "Unibet"             
##  [4] "BetRivers"           "FanDuel"             "PointsBet (US)"     
##  [7] "BetOnline.ag"        "BetMGM"              "Barstool Sportsbook"
## [10] "Bovada"
## Invalid bookmaker format:
##  [1] "2023-09-17T16:55:26Z" "2023-09-17T16:55:26Z" "2023-09-17T16:55:27Z"
##  [4] "2023-09-17T16:55:27Z" "2023-09-17T16:55:26Z" "2023-09-17T16:55:25Z"
##  [7] "2023-09-17T16:55:25Z" "2023-09-17T16:55:26Z" "2023-09-17T16:55:27Z"
## [10] "2023-09-17T16:55:26Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "draftkings"     "unibet_us"      "betrivers"      "williamhill_us"
##  [5] "betonlineag"    "fanduel"        "pointsbetus"    "barstool"      
##  [9] "betmgm"         "bovada"
## Invalid bookmaker format:
##  [1] "DraftKings"          "Unibet"              "BetRivers"          
##  [4] "William Hill (US)"   "BetOnline.ag"        "FanDuel"            
##  [7] "PointsBet (US)"      "Barstool Sportsbook" "BetMGM"             
## [10] "Bovada"
## Invalid bookmaker format:
##  [1] "2023-09-17T16:55:26Z" "2023-09-17T16:55:27Z" "2023-09-17T16:55:27Z"
##  [4] "2023-09-17T16:55:26Z" "2023-09-17T16:55:25Z" "2023-09-17T16:55:26Z"
##  [7] "2023-09-17T16:55:25Z" "2023-09-17T16:55:27Z" "2023-09-17T16:55:26Z"
## [10] "2023-09-17T16:55:26Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "draftkings"     "williamhill_us" "unibet_us"      "betrivers"     
##  [5] "fanduel"        "betonlineag"    "pointsbetus"    "barstool"      
##  [9] "betmgm"         "bovada"
## Invalid bookmaker format:
##  [1] "DraftKings"          "William Hill (US)"   "Unibet"             
##  [4] "BetRivers"           "FanDuel"             "BetOnline.ag"       
##  [7] "PointsBet (US)"      "Barstool Sportsbook" "BetMGM"             
## [10] "Bovada"
## Invalid bookmaker format:
##  [1] "2023-09-17T16:55:26Z" "2023-09-17T16:55:26Z" "2023-09-17T16:55:27Z"
##  [4] "2023-09-17T16:55:27Z" "2023-09-17T16:55:26Z" "2023-09-17T16:55:25Z"
##  [7] "2023-09-17T16:55:25Z" "2023-09-17T16:55:27Z" "2023-09-17T16:55:26Z"
## [10] "2023-09-17T16:55:26Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "draftkings"     "williamhill_us" "unibet_us"      "betrivers"     
##  [5] "fanduel"        "betonlineag"    "pointsbetus"    "barstool"      
##  [9] "betmgm"         "bovada"
## Invalid bookmaker format:
##  [1] "DraftKings"          "William Hill (US)"   "Unibet"             
##  [4] "BetRivers"           "FanDuel"             "BetOnline.ag"       
##  [7] "PointsBet (US)"      "Barstool Sportsbook" "BetMGM"             
## [10] "Bovada"
## Invalid bookmaker format:
##  [1] "2023-09-17T16:55:26Z" "2023-09-17T16:55:26Z" "2023-09-17T16:55:27Z"
##  [4] "2023-09-17T16:55:27Z" "2023-09-17T16:55:26Z" "2023-09-17T16:55:25Z"
##  [7] "2023-09-17T16:55:25Z" "2023-09-17T16:55:27Z" "2023-09-17T16:55:26Z"
## [10] "2023-09-17T16:55:26Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "draftkings"     "williamhill_us" "unibet_us"      "betrivers"     
##  [5] "fanduel"        "pointsbetus"    "betonlineag"    "betmgm"        
##  [9] "barstool"       "bovada"
## Invalid bookmaker format:
##  [1] "DraftKings"          "William Hill (US)"   "Unibet"             
##  [4] "BetRivers"           "FanDuel"             "PointsBet (US)"     
##  [7] "BetOnline.ag"        "BetMGM"              "Barstool Sportsbook"
## [10] "Bovada"
## Invalid bookmaker format:
##  [1] "2023-09-17T16:55:26Z" "2023-09-17T16:55:26Z" "2023-09-17T16:55:27Z"
##  [4] "2023-09-17T16:55:27Z" "2023-09-17T16:55:26Z" "2023-09-17T16:55:25Z"
##  [7] "2023-09-17T16:55:25Z" "2023-09-17T16:55:26Z" "2023-09-17T16:55:27Z"
## [10] "2023-09-17T16:55:26Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "draftkings"     "williamhill_us" "unibet_us"      "betrivers"     
##  [5] "fanduel"        "pointsbetus"    "barstool"       "betonlineag"   
##  [9] "betmgm"         "bovada"
## Invalid bookmaker format:
##  [1] "DraftKings"          "William Hill (US)"   "Unibet"             
##  [4] "BetRivers"           "FanDuel"             "PointsBet (US)"     
##  [7] "Barstool Sportsbook" "BetOnline.ag"        "BetMGM"             
## [10] "Bovada"
## Invalid bookmaker format:
##  [1] "2023-09-17T16:55:26Z" "2023-09-17T16:55:26Z" "2023-09-17T16:55:27Z"
##  [4] "2023-09-17T16:55:27Z" "2023-09-17T16:55:26Z" "2023-09-17T16:55:25Z"
##  [7] "2023-09-17T16:55:27Z" "2023-09-17T16:55:25Z" "2023-09-17T16:55:26Z"
## [10] "2023-09-17T16:55:26Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "draftkings"     "williamhill_us" "unibet_us"      "betrivers"     
##  [5] "fanduel"        "pointsbetus"    "barstool"       "betonlineag"   
##  [9] "betmgm"         "bovada"
## Invalid bookmaker format:
##  [1] "DraftKings"          "William Hill (US)"   "Unibet"             
##  [4] "BetRivers"           "FanDuel"             "PointsBet (US)"     
##  [7] "Barstool Sportsbook" "BetOnline.ag"        "BetMGM"             
## [10] "Bovada"
## Invalid bookmaker format:
##  [1] "2023-09-17T16:55:26Z" "2023-09-17T16:55:26Z" "2023-09-17T16:55:27Z"
##  [4] "2023-09-17T16:55:27Z" "2023-09-17T16:55:26Z" "2023-09-17T16:55:25Z"
##  [7] "2023-09-17T16:55:27Z" "2023-09-17T16:55:25Z" "2023-09-17T16:55:26Z"
## [10] "2023-09-17T16:55:26Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
## [1] "draftkings"  "unibet_us"   "fanduel"     "pointsbetus" "bovada"
## Invalid bookmaker format:
## [1] "DraftKings"     "Unibet"         "FanDuel"        "PointsBet (US)"
## [5] "Bovada"
## Invalid bookmaker format:
## [1] "2023-09-17T17:55:26Z" "2023-09-17T17:55:27Z" "2023-09-17T17:54:26Z"
## [4] "2023-09-17T17:55:25Z" "2023-09-17T17:55:25Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "draftkings"     "williamhill_us" "unibet_us"      "betrivers"     
##  [5] "fanduel"        "betonlineag"    "pointsbetus"    "betmgm"        
##  [9] "bovada"         "barstool"
## Invalid bookmaker format:
##  [1] "DraftKings"          "William Hill (US)"   "Unibet"             
##  [4] "BetRivers"           "FanDuel"             "BetOnline.ag"       
##  [7] "PointsBet (US)"      "BetMGM"              "Bovada"             
## [10] "Barstool Sportsbook"
## Invalid bookmaker format:
##  [1] "2023-09-17T20:00:28Z" "2023-09-17T20:00:28Z" "2023-09-17T20:00:29Z"
##  [4] "2023-09-17T20:00:29Z" "2023-09-17T20:00:29Z" "2023-09-17T20:00:28Z"
##  [7] "2023-09-17T20:00:28Z" "2023-09-17T20:00:29Z" "2023-09-17T20:00:28Z"
## [10] "2023-09-17T20:00:29Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "draftkings"     "williamhill_us" "unibet_us"      "betrivers"     
##  [5] "fanduel"        "betonlineag"    "pointsbetus"    "barstool"      
##  [9] "betmgm"         "bovada"
## Invalid bookmaker format:
##  [1] "DraftKings"          "William Hill (US)"   "Unibet"             
##  [4] "BetRivers"           "FanDuel"             "BetOnline.ag"       
##  [7] "PointsBet (US)"      "Barstool Sportsbook" "BetMGM"             
## [10] "Bovada"
## Invalid bookmaker format:
##  [1] "2023-09-17T20:00:28Z" "2023-09-17T20:00:28Z" "2023-09-17T20:00:29Z"
##  [4] "2023-09-17T19:59:25Z" "2023-09-17T20:00:29Z" "2023-09-17T20:00:28Z"
##  [7] "2023-09-17T20:00:28Z" "2023-09-17T20:00:29Z" "2023-09-17T20:00:29Z"
## [10] "2023-09-17T20:00:28Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "draftkings"     "williamhill_us" "unibet_us"      "betrivers"     
##  [5] "betonlineag"    "fanduel"        "pointsbetus"    "betmgm"        
##  [9] "barstool"       "bovada"
## Invalid bookmaker format:
##  [1] "DraftKings"          "William Hill (US)"   "Unibet"             
##  [4] "BetRivers"           "BetOnline.ag"        "FanDuel"            
##  [7] "PointsBet (US)"      "BetMGM"              "Barstool Sportsbook"
## [10] "Bovada"
## Invalid bookmaker format:
##  [1] "2023-09-17T20:19:54Z" "2023-09-17T20:19:55Z" "2023-09-17T20:19:55Z"
##  [4] "2023-09-17T20:19:55Z" "2023-09-17T20:20:19Z" "2023-09-17T20:20:19Z"
##  [7] "2023-09-17T20:20:19Z" "2023-09-17T20:20:19Z" "2023-09-17T20:19:55Z"
## [10] "2023-09-17T20:19:56Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "draftkings"     "williamhill_us" "unibet_us"      "betrivers"     
##  [5] "betonlineag"    "fanduel"        "pointsbetus"    "barstool"      
##  [9] "betmgm"         "bovada"
## Invalid bookmaker format:
##  [1] "DraftKings"          "William Hill (US)"   "Unibet"             
##  [4] "BetRivers"           "BetOnline.ag"        "FanDuel"            
##  [7] "PointsBet (US)"      "Barstool Sportsbook" "BetMGM"             
## [10] "Bovada"
## Invalid bookmaker format:
##  [1] "2023-09-17T20:19:54Z" "2023-09-17T20:19:55Z" "2023-09-17T20:19:55Z"
##  [4] "2023-09-17T20:19:55Z" "2023-09-17T20:20:19Z" "2023-09-17T20:20:19Z"
##  [7] "2023-09-17T20:20:19Z" "2023-09-17T20:19:55Z" "2023-09-17T20:20:19Z"
## [10] "2023-09-17T20:19:56Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "draftkings"     "williamhill_us" "unibet_us"      "betrivers"     
##  [5] "betonlineag"    "fanduel"        "pointsbetus"    "barstool"      
##  [9] "betmgm"         "bovada"
## Invalid bookmaker format:
##  [1] "DraftKings"          "William Hill (US)"   "Unibet"             
##  [4] "BetRivers"           "BetOnline.ag"        "FanDuel"            
##  [7] "PointsBet (US)"      "Barstool Sportsbook" "BetMGM"             
## [10] "Bovada"
## Invalid bookmaker format:
##  [1] "2023-09-18T00:14:28Z" "2023-09-18T00:15:31Z" "2023-09-18T00:15:31Z"
##  [4] "2023-09-18T00:15:19Z" "2023-09-18T00:15:04Z" "2023-09-18T00:15:11Z"
##  [7] "2023-09-18T00:15:33Z" "2023-09-18T00:15:31Z" "2023-09-18T00:14:24Z"
## [10] "2023-09-18T00:14:56Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "draftkings"     "williamhill_us" "unibet_us"      "betrivers"     
##  [5] "betonlineag"    "fanduel"        "betmgm"         "barstool"      
##  [9] "pointsbetus"    "bovada"
## Invalid bookmaker format:
##  [1] "DraftKings"          "William Hill (US)"   "Unibet"             
##  [4] "BetRivers"           "BetOnline.ag"        "FanDuel"            
##  [7] "BetMGM"              "Barstool Sportsbook" "PointsBet (US)"     
## [10] "Bovada"
## Invalid bookmaker format:
##  [1] "2023-09-18T23:10:23Z" "2023-09-18T23:10:27Z" "2023-09-18T23:10:03Z"
##  [4] "2023-09-18T23:10:09Z" "2023-09-18T23:10:23Z" "2023-09-18T23:10:09Z"
##  [7] "2023-09-18T23:09:47Z" "2023-09-18T23:10:03Z" "2023-09-18T23:10:10Z"
## [10] "2023-09-18T23:09:40Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "draftkings"     "williamhill_us" "unibet_us"      "betrivers"     
##  [5] "betonlineag"    "fanduel"        "barstool"       "betmgm"        
##  [9] "pointsbetus"    "bovada"
## Invalid bookmaker format:
##  [1] "DraftKings"          "William Hill (US)"   "Unibet"             
##  [4] "BetRivers"           "BetOnline.ag"        "FanDuel"            
##  [7] "Barstool Sportsbook" "BetMGM"              "PointsBet (US)"     
## [10] "Bovada"
## Invalid bookmaker format:
##  [1] "2023-09-19T00:10:28Z" "2023-09-19T00:09:51Z" "2023-09-19T00:10:13Z"
##  [4] "2023-09-19T00:10:21Z" "2023-09-19T00:10:08Z" "2023-09-19T00:10:28Z"
##  [7] "2023-09-19T00:10:25Z" "2023-09-19T00:10:25Z" "2023-09-19T00:10:25Z"
## [10] "2023-09-19T00:09:55Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "draftkings"     "williamhill_us" "fanduel"        "unibet_us"     
##  [5] "betrivers"      "betonlineag"    "bovada"         "pointsbetus"   
##  [9] "betmgm"         "barstool"
## Invalid bookmaker format:
##  [1] "DraftKings"          "William Hill (US)"   "FanDuel"            
##  [4] "Unibet"              "BetRivers"           "BetOnline.ag"       
##  [7] "Bovada"              "PointsBet (US)"      "BetMGM"             
## [10] "Barstool Sportsbook"
## Invalid bookmaker format:
##  [1] "2023-09-22T00:10:03Z" "2023-09-22T00:10:05Z" "2023-09-22T00:10:03Z"
##  [4] "2023-09-22T00:10:03Z" "2023-09-22T00:10:04Z" "2023-09-22T00:10:02Z"
##  [7] "2023-09-22T00:10:03Z" "2023-09-22T00:10:17Z" "2023-09-22T00:10:17Z"
## [10] "2023-09-22T00:10:04Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
## [1] "draftkings"     "williamhill_us" "fanduel"        "betrivers"     
## [5] "unibet_us"      "betonlineag"    "pointsbetus"    "betmgm"        
## [9] "barstool"
## Invalid bookmaker format:
## [1] "DraftKings"          "William Hill (US)"   "FanDuel"            
## [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
## [7] "PointsBet (US)"      "BetMGM"              "Barstool Sportsbook"
## Invalid bookmaker format:
## [1] "2023-09-24T16:55:13Z" "2023-09-24T16:55:14Z" "2023-09-24T16:55:15Z"
## [4] "2023-09-24T16:55:15Z" "2023-09-24T16:55:15Z" "2023-09-24T16:55:13Z"
## [7] "2023-09-24T16:55:13Z" "2023-09-24T16:55:14Z" "2023-09-24T16:55:15Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
## [1] "draftkings"     "williamhill_us" "fanduel"        "betrivers"     
## [5] "unibet_us"      "betonlineag"    "pointsbetus"    "barstool"
## Invalid bookmaker format:
## [1] "DraftKings"          "William Hill (US)"   "FanDuel"            
## [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
## [7] "PointsBet (US)"      "Barstool Sportsbook"
## Invalid bookmaker format:
## [1] "2023-09-24T16:55:13Z" "2023-09-24T16:55:14Z" "2023-09-24T16:55:15Z"
## [4] "2023-09-24T16:55:15Z" "2023-09-24T16:55:15Z" "2023-09-24T16:55:13Z"
## [7] "2023-09-24T16:55:13Z" "2023-09-24T16:55:15Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
## [1] "draftkings"     "williamhill_us" "fanduel"        "betrivers"     
## [5] "unibet_us"      "betonlineag"    "betmgm"         "pointsbetus"   
## [9] "barstool"
## Invalid bookmaker format:
## [1] "DraftKings"          "William Hill (US)"   "FanDuel"            
## [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
## [7] "BetMGM"              "PointsBet (US)"      "Barstool Sportsbook"
## Invalid bookmaker format:
## [1] "2023-09-24T16:55:13Z" "2023-09-24T16:55:14Z" "2023-09-24T16:55:15Z"
## [4] "2023-09-24T16:55:15Z" "2023-09-24T16:55:15Z" "2023-09-24T16:55:13Z"
## [7] "2023-09-24T16:55:14Z" "2023-09-24T16:55:13Z" "2023-09-24T16:55:15Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
## [1] "draftkings"     "williamhill_us" "fanduel"        "betrivers"     
## [5] "unibet_us"      "betonlineag"    "pointsbetus"    "betmgm"        
## [9] "barstool"
## Invalid bookmaker format:
## [1] "DraftKings"          "William Hill (US)"   "FanDuel"            
## [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
## [7] "PointsBet (US)"      "BetMGM"              "Barstool Sportsbook"
## Invalid bookmaker format:
## [1] "2023-09-24T16:55:13Z" "2023-09-24T16:55:14Z" "2023-09-24T16:55:15Z"
## [4] "2023-09-24T16:51:44Z" "2023-09-24T16:55:15Z" "2023-09-24T16:55:13Z"
## [7] "2023-09-24T16:55:13Z" "2023-09-24T16:46:48Z" "2023-09-24T16:55:15Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
##  [1] "draftkings"     "williamhill_us" "fanduel"        "betrivers"     
##  [5] "unibet_us"      "betonlineag"    "bovada"         "pointsbetus"   
##  [9] "betmgm"         "barstool"
## Invalid bookmaker format:
##  [1] "DraftKings"          "William Hill (US)"   "FanDuel"            
##  [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
##  [7] "Bovada"              "PointsBet (US)"      "BetMGM"             
## [10] "Barstool Sportsbook"
## Invalid bookmaker format:
##  [1] "2023-09-24T16:55:13Z" "2023-09-24T16:55:14Z" "2023-09-24T16:55:15Z"
##  [4] "2023-09-24T16:55:15Z" "2023-09-24T16:55:15Z" "2023-09-24T16:55:13Z"
##  [7] "2023-09-24T16:55:13Z" "2023-09-24T16:55:13Z" "2023-09-24T16:55:14Z"
## [10] "2023-09-24T16:55:15Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
## [1] "draftkings"     "williamhill_us" "fanduel"        "unibet_us"     
## [5] "betrivers"      "betonlineag"    "betmgm"         "pointsbetus"   
## [9] "barstool"
## Invalid bookmaker format:
## [1] "DraftKings"          "William Hill (US)"   "FanDuel"            
## [4] "Unibet"              "BetRivers"           "BetOnline.ag"       
## [7] "BetMGM"              "PointsBet (US)"      "Barstool Sportsbook"
## Invalid bookmaker format:
## [1] "2023-09-24T16:55:13Z" "2023-09-24T16:55:14Z" "2023-09-24T16:55:15Z"
## [4] "2023-09-24T16:55:15Z" "2023-09-24T16:55:15Z" "2023-09-24T16:55:13Z"
## [7] "2023-09-24T16:55:14Z" "2023-09-24T16:55:13Z" "2023-09-24T16:55:15Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
## [1] "draftkings"     "williamhill_us" "fanduel"        "betrivers"     
## [5] "unibet_us"      "betonlineag"    "pointsbetus"    "betmgm"        
## [9] "barstool"
## Invalid bookmaker format:
## [1] "DraftKings"          "William Hill (US)"   "FanDuel"            
## [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
## [7] "PointsBet (US)"      "BetMGM"              "Barstool Sportsbook"
## Invalid bookmaker format:
## [1] "2023-09-24T16:55:13Z" "2023-09-24T16:55:14Z" "2023-09-24T16:55:15Z"
## [4] "2023-09-24T16:55:15Z" "2023-09-24T16:55:15Z" "2023-09-24T16:55:13Z"
## [7] "2023-09-24T16:55:13Z" "2023-09-24T16:55:14Z" "2023-09-24T16:55:15Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
## [1] "draftkings"     "williamhill_us" "fanduel"        "betonlineag"   
## [5] "unibet_us"      "betrivers"      "pointsbetus"    "bovada"        
## [9] "barstool"
## Invalid bookmaker format:
## [1] "DraftKings"          "William Hill (US)"   "FanDuel"            
## [4] "BetOnline.ag"        "Unibet"              "BetRivers"          
## [7] "PointsBet (US)"      "Bovada"              "Barstool Sportsbook"
## Invalid bookmaker format:
## [1] "2023-09-24T16:55:13Z" "2023-09-24T16:55:14Z" "2023-09-24T16:55:15Z"
## [4] "2023-09-24T16:55:13Z" "2023-09-24T16:55:15Z" "2023-09-24T16:55:15Z"
## [7] "2023-09-24T16:55:13Z" "2023-09-24T16:55:13Z" "2023-09-24T16:55:15Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
## [1] "draftkings"     "williamhill_us" "fanduel"        "betrivers"     
## [5] "unibet_us"      "betonlineag"    "bovada"         "pointsbetus"   
## [9] "barstool"
## Invalid bookmaker format:
## [1] "DraftKings"          "William Hill (US)"   "FanDuel"            
## [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
## [7] "Bovada"              "PointsBet (US)"      "Barstool Sportsbook"
## Invalid bookmaker format:
## [1] "2023-09-24T16:55:13Z" "2023-09-24T16:55:14Z" "2023-09-24T16:55:15Z"
## [4] "2023-09-24T16:55:15Z" "2023-09-24T16:55:15Z" "2023-09-24T16:55:13Z"
## [7] "2023-09-24T16:55:13Z" "2023-09-24T16:55:13Z" "2023-09-24T16:55:15Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
## [1] "draftkings"     "williamhill_us" "fanduel"        "unibet_us"     
## [5] "betrivers"      "betonlineag"    "pointsbetus"    "betmgm"        
## [9] "barstool"
## Invalid bookmaker format:
## [1] "DraftKings"          "William Hill (US)"   "FanDuel"            
## [4] "Unibet"              "BetRivers"           "BetOnline.ag"       
## [7] "PointsBet (US)"      "BetMGM"              "Barstool Sportsbook"
## Invalid bookmaker format:
## [1] "2023-09-24T20:00:28Z" "2023-09-24T20:00:02Z" "2023-09-24T20:00:27Z"
## [4] "2023-09-24T20:00:28Z" "2023-09-24T20:00:28Z" "2023-09-24T20:00:28Z"
## [7] "2023-09-24T20:00:28Z" "2023-09-24T20:00:28Z" "2023-09-24T20:00:28Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
## [1] "draftkings"     "williamhill_us" "fanduel"        "unibet_us"     
## [5] "betrivers"      "betonlineag"    "pointsbetus"    "barstool"
## Invalid bookmaker format:
## [1] "DraftKings"          "William Hill (US)"   "FanDuel"            
## [4] "Unibet"              "BetRivers"           "BetOnline.ag"       
## [7] "PointsBet (US)"      "Barstool Sportsbook"
## Invalid bookmaker format:
## [1] "2023-09-24T20:20:15Z" "2023-09-24T20:19:18Z" "2023-09-24T20:20:15Z"
## [4] "2023-09-24T20:20:16Z" "2023-09-24T20:20:15Z" "2023-09-24T20:20:14Z"
## [7] "2023-09-24T20:20:14Z" "2023-09-24T20:20:27Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
## [1] "draftkings"     "williamhill_us" "fanduel"        "betrivers"     
## [5] "unibet_us"      "betonlineag"    "bovada"         "pointsbetus"   
## [9] "barstool"
## Invalid bookmaker format:
## [1] "DraftKings"          "William Hill (US)"   "FanDuel"            
## [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
## [7] "Bovada"              "PointsBet (US)"      "Barstool Sportsbook"
## Invalid bookmaker format:
## [1] "2023-09-24T20:20:15Z" "2023-09-24T20:19:18Z" "2023-09-24T20:20:15Z"
## [4] "2023-09-24T20:20:15Z" "2023-09-24T20:20:16Z" "2023-09-24T20:20:14Z"
## [7] "2023-09-24T20:20:15Z" "2023-09-24T20:20:14Z" "2023-09-24T20:20:27Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
## [1] "draftkings"     "williamhill_us" "fanduel"        "betrivers"     
## [5] "unibet_us"      "betonlineag"    "pointsbetus"    "barstool"
## Invalid bookmaker format:
## [1] "DraftKings"          "William Hill (US)"   "FanDuel"            
## [4] "BetRivers"           "Unibet"              "BetOnline.ag"       
## [7] "PointsBet (US)"      "Barstool Sportsbook"
## Invalid bookmaker format:
## [1] "2023-09-25T00:15:32Z" "2023-09-25T00:14:54Z" "2023-09-25T00:15:33Z"
## [4] "2023-09-25T00:15:05Z" "2023-09-25T00:15:32Z" "2023-09-25T00:15:16Z"
## [7] "2023-09-25T00:15:35Z" "2023-09-25T00:15:32Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
## [1] "draftkings"     "williamhill_us" "fanduel"        "betonlineag"   
## [5] "unibet_us"      "betrivers"      "betmgm"         "barstool"      
## [9] "pointsbetus"
## Invalid bookmaker format:
## [1] "DraftKings"          "William Hill (US)"   "FanDuel"            
## [4] "BetOnline.ag"        "Unibet"              "BetRivers"          
## [7] "BetMGM"              "Barstool Sportsbook" "PointsBet (US)"
## Invalid bookmaker format:
## [1] "2023-09-25T23:10:33Z" "2023-09-25T23:10:27Z" "2023-09-25T23:10:33Z"
## [4] "2023-09-25T23:10:33Z" "2023-09-25T23:10:27Z" "2023-09-25T23:10:28Z"
## [7] "2023-09-25T23:09:40Z" "2023-09-25T23:09:59Z" "2023-09-25T23:10:27Z"
## Skipping invalid or empty markets for bookmaker: 
## Invalid bookmaker format:
## [1] "draftkings"     "williamhill_us" "fanduel"        "unibet_us"     
## [5] "betrivers"      "betonlineag"    "betmgm"         "pointsbetus"   
## [9] "barstool"
## Invalid bookmaker format:
## [1] "DraftKings"          "William Hill (US)"   "FanDuel"            
## [4] "Unibet"              "BetRivers"           "BetOnline.ag"       
## [7] "BetMGM"              "PointsBet (US)"      "Barstool Sportsbook"
## Invalid bookmaker format:
## [1] "2023-09-26T00:10:05Z" "2023-09-26T00:10:21Z" "2023-09-26T00:10:29Z"
## [4] "2023-09-26T00:10:05Z" "2023-09-26T00:09:56Z" "2023-09-26T00:10:29Z"
## [7] "2023-09-26T00:08:53Z" "2023-09-26T00:10:14Z" "2023-09-26T00:09:55Z"
## Skipping invalid or empty markets for bookmaker:
## Failed to fetch data for event ID: 64d2cc01eb7414bb4a85a3f08cb3ab51
## Invalid bookmaker format:
## [1] "fanduel"        "draftkings"     "betonlineag"    "williamhill_us"
## [5] "betrivers"      "unibet_us"      "pointsbetus"    "barstool"
## Invalid bookmaker format:
## [1] "FanDuel"             "DraftKings"          "BetOnline.ag"       
## [4] "William Hill (US)"   "BetRivers"           "Unibet"             
## [7] "PointsBet (US)"      "Barstool Sportsbook"
## Invalid bookmaker format:
## [1] "2023-10-01T13:24:45Z" "2023-10-01T13:24:45Z" "2023-10-01T13:24:45Z"
## [4] "2023-10-01T13:22:11Z" "2023-10-01T13:24:46Z" "2023-10-01T13:24:46Z"
## [7] "2023-10-01T13:24:45Z" "2023-10-01T13:24:46Z"
## Skipping invalid or empty markets for bookmaker:
## Failed to fetch data for event ID: 0eba74e823091ef0c018db3186d6d9f4
## Failed to fetch data for event ID: 21bb40c5a5ceee50be3c920b4ae63d49
## Failed to fetch data for event ID: 83690cd5137dd21957b5f7e5f0d69ce8
## Failed to fetch data for event ID: 57ffc446e97c819dc2a70b975bb8137a
## Failed to fetch data for event ID: 878191e32205fb5d1d128e296991bd2f
## Failed to fetch data for event ID: e959481a2f901e068329dd6c3acdb0b8
## Failed to fetch data for event ID: 8309916190181e1c0b721d63ba48175b
## Failed to fetch data for event ID: af76fc8f89b894ebf7d38bd342c6b891
## Failed to fetch data for event ID: 8eb8b5d38368fbe9b7d2aeddee9389a3
## Failed to fetch data for event ID: 332627137e6b3bebf649665ca0b87012
## Failed to fetch data for event ID: 86195a9d8c1db6044937aceee9121308
## Failed to fetch data for event ID: 5c43ea90317b1704021f18776d3f4a34
## Failed to fetch data for event ID: 1fc413cbbf2bd5749a9b4e195f6ed6e1
## Failed to fetch data for event ID: d684cdd0a0e7b59565cf88ca5d98a216
## Failed to fetch data for event ID: 8942fe69e281c9ba159c2f7aad463913
## Invalid bookmaker format:
## [1] "fanduel"     "draftkings"  "betonlineag" "unibet_us"   "betrivers"  
## [6] "pointsbetus" "barstool"    "betmgm"
## Invalid bookmaker format:
## [1] "FanDuel"             "DraftKings"          "BetOnline.ag"       
## [4] "Unibet"              "BetRivers"           "PointsBet (US)"     
## [7] "Barstool Sportsbook" "BetMGM"
## Invalid bookmaker format:
## [1] "2023-10-08T13:24:42Z" "2023-10-08T13:24:41Z" "2023-10-08T13:24:41Z"
## [4] "2023-10-08T13:24:42Z" "2023-10-08T13:24:43Z" "2023-10-08T13:24:41Z"
## [7] "2023-10-08T13:24:42Z" "2023-10-08T13:24:41Z"
## Skipping invalid or empty markets for bookmaker:
## Failed to fetch data for event ID: c5eb13dd3495fa5bc7d6c6b7516ca720
## Failed to fetch data for event ID: 98ca9ce220c26ef58cfdbaf0312beed8
## Failed to fetch data for event ID: 4c1521d442b80d7f0d6459e8b42e22d7
## Failed to fetch data for event ID: 8dae05c92e2c64a0e7cabc27503c395d
## Failed to fetch data for event ID: 6ed123d675ff7026b7b8ae34d3b4a59f
## Failed to fetch data for event ID: b9ec5b04fe8be3598c8bbfb01f27e70b
## Failed to fetch data for event ID: ad1d9db96233af5b2b4cca4230cdf602
## Failed to fetch data for event ID: b0c7f9b63b5788ae40e60510364a1af2
## Failed to fetch data for event ID: a3f5d603e7282b68208cb10fdf36d527
## Failed to fetch data for event ID: 8d1444ecf7d58af5e4c2d4133992c0c3
## Failed to fetch data for event ID: 83b372f4210309fc21611f6e5432393a
## Failed to fetch data for event ID: 9ad60af78054a9f56c65d6a4f9859c0b
## Failed to fetch data for event ID: d817435dd756fd63bf5b95d57ccd2c2f
## Invalid bookmaker format:
##  [1] "fanduel"        "draftkings"     "williamhill_us" "betonlineag"   
##  [5] "bovada"         "betrivers"      "unibet_us"      "pointsbetus"   
##  [9] "betmgm"         "barstool"
## Invalid bookmaker format:
##  [1] "FanDuel"             "DraftKings"          "Caesars"            
##  [4] "BetOnline.ag"        "Bovada"              "BetRivers"          
##  [7] "Unibet"              "PointsBet (US)"      "BetMGM"             
## [10] "Barstool Sportsbook"
## Invalid bookmaker format:
##  [1] "2023-10-15T13:25:26Z" "2023-10-15T13:25:26Z" "2023-10-15T13:25:27Z"
##  [4] "2023-10-15T13:25:07Z" "2023-10-15T13:25:11Z" "2023-10-15T13:25:07Z"
##  [7] "2023-10-15T13:25:33Z" "2023-10-15T13:24:46Z" "2023-10-15T13:24:47Z"
## [10] "2023-10-15T13:25:05Z"
## Skipping invalid or empty markets for bookmaker:
## Failed to fetch data for event ID: fac6e54ea982e21de9d9710b435b9f1d
## Failed to fetch data for event ID: 39c57be9aa8845c80d4e624548d0a189
## Failed to fetch data for event ID: c600e3c25b26ff9f010d25d4f2597983
## Failed to fetch data for event ID: c52cd634f65ea3f381b44d9b6508e784
## Failed to fetch data for event ID: 640fd44761340126d8d482cd2a819c4a
## Failed to fetch data for event ID: 436514c3dbf06d14bf6a2f3ae0342e72
## Failed to fetch data for event ID: f0582d8bff257127411169703d1e4b5e
## Failed to fetch data for event ID: 4b857cf9cd52eb84da779be631d09c9a
## Failed to fetch data for event ID: 16c42a31d64515456a664316d5437a59
## Failed to fetch data for event ID: 2b982be329036f42b28534266e322952
## Failed to fetch data for event ID: dc62a556db6973a28f64ca28481850f8
## Failed to fetch data for event ID: a9dd32ca4851d736514da497d2a24bbb
## Failed to fetch data for event ID: c03aaad2365c9337e422b333cddf629d
# Combine all collected props into a single dataframe
player_props_data <- bind_rows(player_props_list)

# Preview the data
print(head(player_props_data))
## # A tibble: 0 × 0
# Initialize a list to store the parsed data
player_props_list <- list()
# Loop through events and extract player reception yards
for (i in seq_len(nrow(limited_events))) {
  event_id <- limited_events$id[i]
  # Construct the API endpoint for the specific event
  url <- paste0("https://api.the-odds-api.com/v4/historical/sports/americanfootball_nfl/events/",
                event_id,
                "/odds")
  # Make the API request
  response <- GET(
    url = url,
    query = list(
      apiKey = api_key,
      regions = "us",
      markets = "player_reception_yds",  # Specify the market for player props
      date = limited_events$commence_time[i]
    )
  )
  # Check if the request was successful
  if (status_code(response) != 200) {
    message("Failed to fetch data for event ID: ", event_id)
    next
  }
  # Parse the response content
  content_data <- content(response, as = "parsed", simplifyVector = FALSE)
  # Check if `data` and `bookmakers` fields exist
  if (!is.null(content_data$data) && !is.null(content_data$data$bookmakers)) {
    for (bookmaker in content_data$data$bookmakers) {
      if (is.list(bookmaker$markets)) {  # Ensure markets is a list
        for (market in bookmaker$markets) {
          if (market$key == "player_reception_yds") {
            # Extract outcomes
            outcomes <- market$outcomes[[1]]
            if (!is.null(outcomes)) {
              # Create a data frame for this market
              market_data <- tibble(
                player = outcomes$description,
                bet_type = outcomes$name,
                odds = outcomes$price,
                point = outcomes$point,
                bookmaker = bookmaker$key,
                event_id = event_id,
                home_team = content_data$data$home_team,
                away_team = content_data$data$away_team,
                commence_time = content_data$data$commence_time
              )
              # Append to the list
              player_props_list[[length(player_props_list) + 1]] <- market_data
            }
          }
        }
      }
    }
  } else {
    message("No bookmakers or markets found for event ID: ", event_id)
  }
}
## Failed to fetch data for event ID: 64d2cc01eb7414bb4a85a3f08cb3ab51
## Failed to fetch data for event ID: 0eba74e823091ef0c018db3186d6d9f4
## Failed to fetch data for event ID: 21bb40c5a5ceee50be3c920b4ae63d49
## Failed to fetch data for event ID: 83690cd5137dd21957b5f7e5f0d69ce8
## Failed to fetch data for event ID: 57ffc446e97c819dc2a70b975bb8137a
## Failed to fetch data for event ID: 878191e32205fb5d1d128e296991bd2f
## Failed to fetch data for event ID: e959481a2f901e068329dd6c3acdb0b8
## Failed to fetch data for event ID: 8309916190181e1c0b721d63ba48175b
## Failed to fetch data for event ID: af76fc8f89b894ebf7d38bd342c6b891
## Failed to fetch data for event ID: 8eb8b5d38368fbe9b7d2aeddee9389a3
## Failed to fetch data for event ID: 332627137e6b3bebf649665ca0b87012
## Failed to fetch data for event ID: 86195a9d8c1db6044937aceee9121308
## Failed to fetch data for event ID: 5c43ea90317b1704021f18776d3f4a34
## Failed to fetch data for event ID: 1fc413cbbf2bd5749a9b4e195f6ed6e1
## Failed to fetch data for event ID: d684cdd0a0e7b59565cf88ca5d98a216
## Failed to fetch data for event ID: 8942fe69e281c9ba159c2f7aad463913
## Failed to fetch data for event ID: c5eb13dd3495fa5bc7d6c6b7516ca720
## Failed to fetch data for event ID: 98ca9ce220c26ef58cfdbaf0312beed8
## Failed to fetch data for event ID: 4c1521d442b80d7f0d6459e8b42e22d7
## Failed to fetch data for event ID: 8dae05c92e2c64a0e7cabc27503c395d
## Failed to fetch data for event ID: 6ed123d675ff7026b7b8ae34d3b4a59f
## Failed to fetch data for event ID: b9ec5b04fe8be3598c8bbfb01f27e70b
## Failed to fetch data for event ID: ad1d9db96233af5b2b4cca4230cdf602
## Failed to fetch data for event ID: b0c7f9b63b5788ae40e60510364a1af2
## Failed to fetch data for event ID: a3f5d603e7282b68208cb10fdf36d527
## Failed to fetch data for event ID: 8d1444ecf7d58af5e4c2d4133992c0c3
## Failed to fetch data for event ID: 83b372f4210309fc21611f6e5432393a
## Failed to fetch data for event ID: 9ad60af78054a9f56c65d6a4f9859c0b
## Failed to fetch data for event ID: d817435dd756fd63bf5b95d57ccd2c2f
## Failed to fetch data for event ID: fac6e54ea982e21de9d9710b435b9f1d
## Failed to fetch data for event ID: 39c57be9aa8845c80d4e624548d0a189
## Failed to fetch data for event ID: c600e3c25b26ff9f010d25d4f2597983
## Failed to fetch data for event ID: c52cd634f65ea3f381b44d9b6508e784
## Failed to fetch data for event ID: 640fd44761340126d8d482cd2a819c4a
## Failed to fetch data for event ID: 436514c3dbf06d14bf6a2f3ae0342e72
## Failed to fetch data for event ID: f0582d8bff257127411169703d1e4b5e
## Failed to fetch data for event ID: 4b857cf9cd52eb84da779be631d09c9a
## Failed to fetch data for event ID: 16c42a31d64515456a664316d5437a59
## Failed to fetch data for event ID: 2b982be329036f42b28534266e322952
## Failed to fetch data for event ID: dc62a556db6973a28f64ca28481850f8
## Failed to fetch data for event ID: a9dd32ca4851d736514da497d2a24bbb
## Failed to fetch data for event ID: c03aaad2365c9337e422b333cddf629d
# Combine all parsed data into a single data frame
player_props_data <- bind_rows(player_props_list)


# Preview the first few rows of the dataset
print(head(player_props_data))
## # A tibble: 6 × 9
##   player            bet_type  odds point bookmaker  event_id home_team away_team
##   <chr>             <chr>    <dbl> <dbl> <chr>      <chr>    <chr>     <chr>    
## 1 Skyy Moore        Over      1.91  47.5 fanduel    42db668… Kansas C… Detroit …
## 2 Marvin Jones Jr.  Over      1.94  27.5 williamhi… 42db668… Kansas C… Detroit …
## 3 Amon-Ra St. Brown Over      1.87  75.5 pointsbet… 42db668… Kansas C… Detroit …
## 4 Amon-Ra St. Brown Over      1.88  75.5 betrivers  42db668… Kansas C… Detroit …
## 5 Amon-Ra St. Brown Over      1.88  75.5 unibet_us  42db668… Kansas C… Detroit …
## 6 Amon-Ra St. Brown Over      1.88  75.5 betonline… 42db668… Kansas C… Detroit …
## # ℹ 1 more variable: commence_time <chr>

The two chunks of above use several R packages to utilize an API from “The Odds API” to fetch historical NFL betting odds. They parse through the data and create a table that displays NFL player prop odds from games that occured in the 2023 season.

# Cleans the player prop data that was retrieved through the API
cleaned_player_props_data <- player_props_data %>%
  group_by(event_id, player) %>%
  summarise(
    home_team = first(home_team),          
    away_team = first(away_team),          
    commence_time = first(commence_time), 
    avg_odds = round(mean(odds, na.rm = TRUE), 2),  
    avg_point = round(mean(point, na.rm = TRUE), 2),
    .groups = "drop"                      
  )
# Game outcome data for player props
library(readr)
all_receptions <- read.csv("https://raw.githubusercontent.com/zachrose97/Data607Final/refs/heads/main/All_Receptions.csv")

colnames(all_receptions)
##  [1] "Rk"     "Player" "Yds"    "Day"    "G."     "Week"   "Date"   "Age"   
##  [9] "Team"   "X"      "Opp"    "Result" "Tgt"    "Rec"    "Yds.1"  "Y.R"   
## [17] "TD"     "Ctch."  "Y.Tgt"  "X1D"    "Succ."  "Pos."   "X.1"
head(all_receptions)
##   Rk        Player Yds Day G. Week      Date    Age Team X Opp       Result Tgt
## 1  1    D.J. Moore 230 Thu  5    5 10/5/2023 26-174  CHI @ WAS      W 40-20  10
## 2  2  Keenan Allen 215 Sun  3    3 9/24/2023 31-150  LAC @ MIN      W 28-24  20
## 3  3   Tyreek Hill 215 Sun  1    1 9/10/2023 29-193  MIA @ LAC      W 36-34  15
## 4  4 Ja'Marr Chase 192 Sun  5    5 10/8/2023 23-221  CIN @ ARI      W 34-20  19
## 5  5   Tyreek Hill 181 Sun  5    5 10/8/2023 29-221  MIA   NYG      W 31-16   9
## 6  6    A.J. Brown 175 Sun  4    4 10/1/2023 26-093  PHI   WAS W 34-31 (OT)  13
##   Rec Yds.1  Y.R TD Ctch. Y.Tgt X1D Succ. Pos. X.1
## 1   8   230 28.8  3  80.0  23.0   6  70.0   WR  NA
## 2  18   215 11.9  0  90.0  10.8  10  65.0   WR  NA
## 3  11   215 19.5  2  73.3  14.3   9  66.7   WR  NA
## 4  15   192 12.8  3  78.9  10.1  14  78.9   WR  NA
## 5   8   181 22.6  1  88.9  20.1   5  88.9   WR  NA
## 6   9   175 19.4  2  69.2  13.5   7  61.5   WR  NA

This code pulls data from a CSV that contains actual player statistic outcomes from the 2023 NFL season.

# Data column cleaning to identify if player belongs to home or away team. 
all_receptions <- all_receptions %>%
  mutate(
    home_team = ifelse(X == "@", Opp, Team),
    away_team = ifelse(X == "@", Team, Opp)
  )
# Data mapping
team_mapping <- data.frame(
  full_name = c(
    "Arizona Cardinals", "Atlanta Falcons", "Baltimore Ravens", "Buffalo Bills", 
    "Carolina Panthers", "Chicago Bears", "Cincinnati Bengals", "Cleveland Browns", 
    "Dallas Cowboys", "Denver Broncos", "Detroit Lions", "Green Bay Packers", 
    "Houston Texans", "Indianapolis Colts", "Jacksonville Jaguars", "Kansas City Chiefs", 
    "Las Vegas Raiders", "Los Angeles Chargers", "Los Angeles Rams", "Miami Dolphins", 
    "Minnesota Vikings", "New England Patriots", "New Orleans Saints", "New York Giants", 
    "New York Jets", "Philadelphia Eagles", "Pittsburgh Steelers", "San Francisco 49ers", 
    "Seattle Seahawks", "Tampa Bay Buccaneers", "Tennessee Titans", "Washington Commanders"
  ),
  acronym = c(
    "ARI", "ATL", "BAL", "BUF", "CAR", "CHI", "CIN", "CLE", "DAL", "DEN", 
    "DET", "GB", "HOU", "IND", "JAX", "KC", "LV", "LAC", "LAR", "MIA", 
    "MIN", "NE", "NO", "NYG", "NYJ", "PHI", "PIT", "SF", "SEA", "TB", 
    "TEN", "WAS"
  )
)

This code attaches the team acronyms from the All_Receptions and turns them into the full team names

cleaned_player_props_data <- cleaned_player_props_data %>%
  left_join(team_mapping, by = c("home_team" = "full_name")) %>%
  rename(home_team_acronym = acronym) %>%
  left_join(team_mapping, by = c("away_team" = "full_name")) %>%
  rename(away_team_acronym = acronym)

This code matches the mapped team names code with the dataset that will be mainly used for analysis, “cleaned_player_props_data”.

library(dplyr)
library(lubridate)

# Defines the start date of the NFL season
nfl_start_date <- as.Date("2023-09-08")

# Adds the week column to cleaned_player_props_data
cleaned_player_props_data <- cleaned_player_props_data %>%
  mutate(
    commence_date = as.Date(commence_time),  # Ensure commence_time is in Date format
    week = ceiling(as.numeric(commence_date - nfl_start_date + 1) / 7)  # Calculate week
  )

# Views the updated dataset
head(cleaned_player_props_data)
## # A tibble: 6 × 11
##   event_id           player home_team away_team commence_time avg_odds avg_point
##   <chr>              <chr>  <chr>     <chr>     <chr>            <dbl>     <dbl>
## 1 0a368c64b212ecbad… A.J. … New Engl… Philadel… 2023-09-10T2…     1.93      69.7
## 2 0a368c64b212ecbad… DeVon… New Engl… Philadel… 2023-09-10T2…     1.86      61.5
## 3 0a368c64b212ecbad… Hunte… New Engl… Philadel… 2023-09-10T2…     1.91      30.5
## 4 0cd8d5597260f1a2c… Chig … Tennesse… Baltimor… 2023-10-15T1…     1.91      26.5
## 5 0cd8d5597260f1a2c… Chigo… Tennesse… Baltimor… 2023-10-15T1…     1.83      26.5
## 6 0cd8d5597260f1a2c… Chris… Tennesse… Baltimor… 2023-10-15T1…     1.8       15.5
## # ℹ 4 more variables: home_team_acronym <chr>, away_team_acronym <chr>,
## #   commence_date <date>, week <dbl>

This code correctly aligns the dates in the dataset using one table’s “commence_time” column and the others “date” column

# Data cleaning
all_receptions <- all_receptions %>%
  rename(player = Player)

This code cleans the palyer column in all_reception to be all lowercase

# Data cleaning
all_receptions <- all_receptions %>%
  filter(!is.na(Week))

all_receptions <- all_receptions %>%
  rename(week = Week)

This code removes empty values from the week column in all receptions, and then standardizes it to be all lower case

# Merges two datasets
merged_data <- cleaned_player_props_data %>%
  inner_join(all_receptions, by = c("player", "week"))

This code merges cleaned_player_props_data and all_receptions by matching player and week columns now that they have both been standardized

merged_data <- merged_data %>%
  mutate(
    result = case_when(
      Yds > avg_point ~ "Over",
      Yds < avg_point ~ "Under",
      TRUE ~ "Push"  # For cases where Yds == avg_point
    )
  )

# Summarize the results
summary_results <- merged_data %>%
  group_by(result) %>%
  summarise(
    count = n(),
    percentage = (n() / nrow(merged_data)) * 100
  )

# View the summary
print(summary_results)
## # A tibble: 2 × 3
##   result count percentage
##   <chr>  <int>      <dbl>
## 1 Over     120       57.7
## 2 Under     88       42.3

This code computes how many of the players from the merged_data dataset went over or under their projected yardage by the sportsbooks.

library(ggplot2)
ggplot(summary_results, aes(x = "", y = percentage, fill = result)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar("y", start = 0) +
  labs(
    title = "Player Props Results Distribution",
    fill = "Result"
  ) +
  theme_void() +
  scale_fill_manual(values = c("Over" = "blue", "Under" = "red"))

A plot showing the distribution in players going over or under expected yardage.

# Data cleaning
merged_data <- merged_data %>%
  select(
    -home_team.y,  # Remove the home team acronym
    -away_team.y   # Remove the away team acronym
  ) %>%
  rename(
    home_team = home_team.x,  # Rename home_team.x to home_team
    away_team = away_team.x   # Rename away_team.x to away_team
  )

This code removes team acronyms from the merged data set, and renames the home and away team names for easier readability.

# Adds a column to classify close spread games
game_table_cleaned <- game_table_cleaned %>%
  mutate(
    close_spread = ifelse(abs(Spread) <= 3, "Close", "Not Close")
  )

# View the distribution of close vs. not close games
table(game_table_cleaned$close_spread)
## 
##     Close Not Close 
##       116       148
player_performance_by_team <- merged_data %>%
  group_by(home_team, away_team) %>%
  summarise(
    total_players = n(),
    over_count = sum(result == "Over"),
    under_count = sum(result == "Under"),
    over_percentage = (over_count / total_players) * 100,
    under_percentage = (under_count / total_players) * 100,
    .groups = "drop"
  )

# View the summary
head(player_performance_by_team)
## # A tibble: 6 × 7
##   home_team       away_team total_players over_count under_count over_percentage
##   <chr>           <chr>             <int>      <int>       <int>           <dbl>
## 1 Arizona Cardin… Dallas C…             4          2           2            50  
## 2 Arizona Cardin… New York…             5          4           1            80  
## 3 Atlanta Falcons Carolina…             3          2           1            66.7
## 4 Atlanta Falcons Green Ba…             5          2           3            40  
## 5 Baltimore Rave… Houston …             5          2           3            40  
## 6 Baltimore Rave… Indianap…             4          3           1            75  
## # ℹ 1 more variable: under_percentage <dbl>

This code breaks down how many players on each team during each game went over or under their expected yardage.

game_table_cleaned <- game_table_cleaned %>%
  distinct(Favorite, Underdog, .keep_all = TRUE)
# Add spread category to game_table_cleaned
game_table_cleaned <- game_table_cleaned %>%
  mutate(spread_category = ifelse(abs(Spread) <= 3, "Close", "Not Close"))

# Perform the join using flexible logic
player_performance_by_spread <- merged_data %>%
  left_join(
    game_table_cleaned %>%
      select(Favorite, Underdog, spread_category, Favorite_Location, Underdog_Location),
    by = c("home_team" = "Favorite", "away_team" = "Underdog")
  ) %>%
  mutate(team_role = ifelse(!is.na(Favorite_Location), "favorite", "underdog")) %>%
  bind_rows(
    merged_data %>%
      left_join(
        game_table_cleaned %>%
          select(Favorite, Underdog, spread_category, Favorite_Location, Underdog_Location),
        by = c("home_team" = "Underdog", "away_team" = "Favorite")
      ) %>%
      mutate(team_role = ifelse(!is.na(Underdog_Location), "underdog", "favorite"))
  )
player_performance_summary <- player_performance_by_spread %>%
  group_by(spread_category) %>%
  summarise(
    avg_over_percentage = mean(result == "Over", na.rm = TRUE),
    .groups = "drop"
  )

# View the results
print(player_performance_summary)
## # A tibble: 3 × 2
##   spread_category avg_over_percentage
##   <chr>                         <dbl>
## 1 Close                         0.637
## 2 Not Close                     0.536
## 3 <NA>                          0.575

This code first adds a spread column to the player performance dataset, it then displays the percentage of players that went over their expected yardage on close spreads, and players that went over on not close spreads.

ggplot(player_performance_summary, aes(x = spread_category, y = avg_over_percentage, fill = spread_category)) +
  geom_bar(stat = "identity", width = 0.7) +
  labs(
    title = "Player Over-Performance by Spread Category",
    x = "Spread Category",
    y = "Average Over Percentage"
  ) +
  theme_minimal() +
  scale_fill_manual(values = c("Close" = "green", "Not Close" = "orange"))

This code creates a visualization of the distribution in these two categories.

team_performance <- merged_data %>%
  left_join(game_table_cleaned, by = c("home_team" = "Favorite", "away_team" = "Underdog")) %>%
  group_by(home_team) %>%
  summarise(
    close_game_over = mean(result == "Over" & spread_category == "Close", na.rm = TRUE),
    not_close_game_over = mean(result == "Over" & spread_category == "Not Close", na.rm = TRUE),
    .groups = "drop"
  )
print(team_performance)
## # A tibble: 32 × 3
##    home_team          close_game_over not_close_game_over
##    <chr>                        <dbl>               <dbl>
##  1 Arizona Cardinals            0                   0    
##  2 Atlanta Falcons              0.5                 0    
##  3 Baltimore Ravens             0                   0.556
##  4 Buffalo Bills                0                   0.5  
##  5 Carolina Panthers          NaN                 NaN    
##  6 Chicago Bears                1                   0    
##  7 Cincinnati Bengals           0                   0.25 
##  8 Cleveland Browns             0                   0.333
##  9 Dallas Cowboys               0                   0.6  
## 10 Denver Broncos               0.286               0.429
## # ℹ 22 more rows

This code attempts to breakdown whether players were more likely to exceed yardage expectations when the game had a close spread. It can be seen here that the Chicago Bears players for example exceeded expectations 100% of the time when the spread was close, but 0% of the time when the spread was not close.

team_performance_outcome <- game_table_cleaned %>%
  group_by(Favorite) %>%
  summarise(
    win_rate = mean(Result == "W"),
    avg_spread = mean(Spread, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  inner_join(team_performance, by = c("Favorite" = "home_team"))

print(team_performance_outcome)
## # A tibble: 30 × 5
##    Favorite           win_rate avg_spread close_game_over not_close_game_over
##    <chr>                 <dbl>      <dbl>           <dbl>               <dbl>
##  1 Atlanta Falcons           0      -2.45           0.5                 0    
##  2 Baltimore Ravens          0      -5.31           0                   0.556
##  3 Buffalo Bills             0      -7.05           0                   0.5  
##  4 Chicago Bears             0      -3.25           1                   0    
##  5 Cincinnati Bengals        0      -2.89           0                   0.25 
##  6 Cleveland Browns          0      -4.75           0                   0.333
##  7 Dallas Cowboys            0      -7.27           0                   0.6  
##  8 Denver Broncos            0      -3              0.286               0.429
##  9 Detroit Lions             0      -4.68           0.375               0.375
## 10 Green Bay Packers         0      -3.42           1                   0    
## # ℹ 20 more rows
merged_data <- merged_data %>%
  left_join(
    game_table_cleaned %>%
      select(Favorite, Underdog, Spread),
    by = c("home_team" = "Favorite", "away_team" = "Underdog")
  )

merged_data <- merged_data %>%
  bind_rows(
    merged_data %>%
      left_join(
        game_table_cleaned %>%
          select(Favorite, Underdog, Spread),
        by = c("home_team" = "Underdog", "away_team" = "Favorite")
      )
  )
player_performance_by_spread <- merged_data %>%
  mutate(
    spread_range = case_when(
      abs(Spread) <= 1 ~ "Very Close",
      abs(Spread) <= 3 ~ "Close",
      TRUE ~ "Not Close"
    )
  ) %>%
  group_by(spread_range) %>%
  summarise(
    avg_over_percentage = mean(result == "Over", na.rm = TRUE),
    .groups = "drop"
  )

# Plot the results
ggplot(player_performance_by_spread, aes(x = spread_range, y = avg_over_percentage, fill = spread_range)) +
  geom_bar(stat = "identity") +
  labs(
    title = "Player Performance by Spread Range",
    x = "Spread Range",
    y = "Average Over Percentage"
  ) +
  theme_minimal()

This code creates a visualization that displays the percentage of players that go over their expected yardage when the spread is considered close, not close, or very close.

In this analysis, the primary goal was to uncover insights into the relationship between betting odds, game outcomes, and individual player performance. Initial expectations included finding a strong correlation between the spread, game location, and outcomes, as well as identifying patterns in wide receiver performance relative to betting projections. However, the results revealed unexpected trends, such as away favorites performing better than anticipated and players exceeding expectations in games with closer spreads. These findings suggest that while bookmakers often favor the home team, reflected in higher spreads for home favorites, the actual dynamics of game outcomes and player performance are more nuanced. There are limitations to the analysis that should be noted. The sample size, particularly for player prop bets, restricts the generalizability of these findings. The API that my data was pulled from was a paid service that limited the number of requests, which hindered my ability to gather more data. Some statistical results, while interesting, did not achieve statistical significance and should be interpreted lightly. Additionally, relying on historical data may not fully capture the changes in team or player performance over time. These limitations showcase opportunities for further exploration and refinement of the approach. Future expansions could include analyzing additional sports or seasons to improve the clarity of the findings and to find broader trends. Incorporating live odds or in-play data may offer real-time insights into betting market behavior, while using machine learning models could help identify hidden patterns and improve predictive capabilities. Despite these limitations, the analysis provides valuable insights, such as the unreliability of betting odds as indicators of game outcomes or player performance and the tendency for players to exceed expectations in games with close spreads. This study shows the potential to deepen understanding of the connection between spreads, outcomes, and player projections, offering useful perspectives for both betters and analysts.