fantasy-football

library(fflr)
packageVersion("fflr")
#> [1] '0.3.12'

The fflr package helps easily access data from the ESPN fantasy football v3 API. Both current and historical data can be

Games

Some functions work independently of your specific league. As of now, this package only works with data from fantasy football leagues, but other fantasy sports exist.

espn_games()
#> # A tibble: 4 x 7
#>   game  active  year pro_league pro_sport  start_date          end_date           
#>   <chr> <lgl>  <int> <chr>      <chr>      <dttm>              <dttm>             
#> 1 FFL   TRUE    2020 NFL        football   2020-03-09 03:00:00 2022-03-09 02:00:00
#> 2 FLB   TRUE    2020 MLB        baseball   2020-01-22 03:00:00 2022-01-22 03:00:00
#> 3 FBA   TRUE    2020 NBA        basketball 2019-06-14 03:00:00 2021-06-14 03:00:00
#> 4 FHL   TRUE    2020 NHL        hockey     2019-07-19 03:00:00 2021-07-19 03:00:00

This package is designed to retrieve both current and historical data from the ESPN API. There are 17 years of seasons listed in the API!

ffl_seasons()
#> # A tibble: 17 x 6
#>    game   year  week pro_league start_date          end_date           
#>    <chr> <int> <int> <chr>      <dttm>              <dttm>             
#>  1 FFL    2020     9 NFL        2020-03-09 03:00:00 2022-03-09 02:00:00
#>  2 FFL    2019    18 NFL        2019-02-06 03:00:00 2020-03-09 03:00:00
#>  3 FFL    2018    18 NFL        2018-01-01 03:00:00 2019-02-06 03:00:00
#>  4 FFL    2017    18 NFL        2017-01-01 03:00:00 2019-01-01 03:00:00
#>  5 FFL    2016    18 NFL        2016-01-01 00:00:00 2018-01-01 00:00:00
#>  6 FFL    2015    18 NFL        2015-01-01 00:00:00 2015-12-31 23:59:59
#>  7 FFL    2014    18 NFL        2014-01-01 00:00:00 2014-12-31 23:59:59
#>  8 FFL    2013    18 NFL        2013-01-01 00:00:00 2013-12-31 23:59:59
#>  9 FFL    2012    18 NFL        2012-01-03 00:00:00 2012-12-31 23:59:59
#> 10 FFL    2011    18 NFL        2011-01-01 00:00:00 2012-01-03 00:00:00
#> 11 FFL    2010    18 NFL        2010-01-04 00:00:00 2011-01-01 00:00:00
#> 12 FFL    2009    18 NFL        2009-01-01 00:00:00 2010-01-04 00:00:00
#> 13 FFL    2008    18 NFL        2008-06-06 00:00:00 2009-01-01 00:00:00
#> 14 FFL    2007    18 NFL        2007-01-01 00:00:00 2008-06-06 00:00:00
#> 15 FFL    2006    18 NFL        2006-01-01 00:00:00 2007-01-01 00:00:00
#> 16 FFL    2005    18 NFL        2005-01-01 00:00:00 2006-01-01 00:00:00
#> 17 FFL    2004    18 NFL        2004-06-01 00:00:00 2005-01-01 00:00:00

The current season and scoring period are pieces of data that can be easily accessed and referenced for data manipulation.

str(ffl_info())
#> List of 6
#>  $ game      : chr "FFL"
#>  $ active    : logi TRUE
#>  $ year      : int 2020
#>  $ week      : int 9
#>  $ start_date: POSIXct[1:1], format: "2020-03-09 03:00:00"
#>  $ end_date  : POSIXct[1:1], format: "2022-03-09 02:00:00"
ffl_year()
#> [1] 2020
ffl_week()
#> [1] 9

To easily refer to past or future years and weeks, simply add an offset integer.

ffl_year(offset = -2)
#> [1] 2018
ffl_week(offset =  1)
#> [1] 10

Leagues

To access data on your league you will need to first use the league manager tools to make your league viewable to the public. This ESPN help page explains how this can be done; the option is found in the basic settings section of the fantasy football website.

Once your league is set to public, you’ll need to find the unique numeric league ID found in the URL of any page. This league ID (LID) is needed to access league specific information like rosters, scores, and transactions.

https://fantasy.espn.com/football/league?leagueId=252353

For convenience, the lid argument to most functions defaults to looking for an “lid” global option. Use options() to set your league ID and put the line in your ~/.Rprofile file to set at start up.

options(lid = 252353)

With our league ID option set, we can now easily retrieve league information.

str(league_info())
#> List of 6
#>  $ year  : int 2020
#>  $ name  : chr "Gambling Addicts Anonymous"
#>  $ id    : int 252353
#>  $ public: logi TRUE
#>  $ size  : int 8
#>  $ length: int 16

As we can see, my league this season has 8 teams and runs for 16 weeks.

Before we look into fantasy scores and player data, we’ll look a little more into how our league is set up.

We can identify the league members and the fantasy teams they own. Fantasy teams can have multiple owners, so team owners are identified by a nested list of unique member hashes.

league_members()
#> # A tibble: 8 x 4
#>    year user              owners                                 lm   
#>   <int> <chr>             <chr>                                  <lgl>
#> 1  2020 Angusg396         {12E61406-349A-4DC7-A614-06349AADC797} FALSE
#> 2  2020 k5cents_          {22DFE7FF-9DF2-4F3B-9FE7-FF9DF2AF3BD2} TRUE 
#> 3  2020 NAudet14          {35D9B7DB-E821-453C-99B7-DBE821353C36} FALSE
#> 4  2020 b.pepe            {5FA14794-6573-4189-A147-9465737189B2} FALSE
#> 5  2020 Billy.Slocum      {91F8B424-1689-472E-B8B4-241689172E35} FALSE
#> 6  2020 ESPNfan0199065799 {9A722A48-6E16-42BC-9E0E-AC9E4E6D7ABC} FALSE
#> 7  2020 espnfan1043876390 {C61F403A-F689-4269-879E-145B897F2308} FALSE
#> 8  2020 MrBruiser12       {F33F0723-2CC3-4A1C-BF07-232CC34A1C15} FALSE

League teams are occasionally only identified by their team number instead of their nickname or abbreviation. The data frame returned by league_teams() can be used to convert these team numbers.

(teams = league_teams())
#> # A tibble: 8 x 5
#>    year  team abbrev owners    name                    
#>   <int> <int> <fct>  <list>    <chr>                   
#> 1  2020     1 AGUS   <chr [1]> Obi-Wan Mahomey         
#> 2  2020     3 PEPE   <chr [1]> JuJu's Bizarre Adventure
#> 3  2020     4 BILL   <chr [1]> Bill's Fantasy Team     
#> 4  2020     5 CART   <chr [1]> Ashley Mattison         
#> 5  2020     6 KIER   <chr [1]> The Nuklear Option      
#> 6  2020     8 CORE   <chr [1]> Fuller Up               
#> 7  2020    10 NICK   <chr [1]> The Silence Of The Lamb 
#> 8  2020    11 KYLE   <chr [1]> Ashley Hill

The team_abbrev() function makes this conversion simple.

team_abbrev(id = 6, teams)
#> [1] KIER
#> Levels: AGUS PEPE BILL CART KIER CORE NICK KYLE

One caveat about the design of this package: most of the functions were designed and tested using the settings from the author’s own fantasy league. Functions relying on certain scoring or roster settings are particularly vulnerable for the time being. These settings can be referenced with the *_settings() functions and may be integrated in the future.

roster_settings()
#> $year
#> [1] 2020
#> 
#> $use_undrop
#> [1] FALSE
#> 
#> $lineup_lock
#> [1] "INDIVIDUAL_GAME"
#> 
#> $roster_lock
#> [1] "INDIVIDUAL_GAME"
#> 
#> $move_limit
#> [1] -1
#> 
#> $slot_count
#> QB RB WR TE DS PK BE IR FX 
#>  1  2  2  1  1  1  7  1  1 
#> 
#> $pos_count
#> QB RB WR TE PK DS 
#>  4  8  8  3  3  3
score_settings()
#> $year
#> [1] 2020
#> 
#> $score_type
#> [1] "H2H_POINTS"
#> 
#> $rank_type
#> [1] "STANDARD"
#> 
#> $home_bonus
#> [1] 0
#> 
#> $playoff_bonus
#> [1] 0
#> 
#> $playoff_tie
#> [1] "NONE"
#> 
#> $scoring
#> # A tibble: 44 x 3
#>     stat points overrides
#>    <int>  <dbl>     <dbl>
#>  1   132      0        -2
#>  2   133      0        -3
#>  3    98      0         4
#>  4    25      6        NA
#>  5   131      0        -1
#>  6   134      0        -4
#>  7    95      0         3
#>  8    72     -2        NA
#>  9   135      0        -5
#> 10   206      2         4
#> # … with 34 more rows

Players

There are over a thousand players in the NFL eligible for fantasy football. The full list of current players can be retrieved at any time.

all_players()
#> # A tibble: 1,072 x 19
#>     year  week     id first last  pro   pos   status start  rost change   prk  fpts   aav   adp
#>    <int> <dbl>  <int> <chr> <chr> <fct> <fct> <chr>  <dbl> <dbl>  <dbl> <int> <dbl> <dbl> <dbl>
#>  1  2020     9 3.05e6 Alvin Kama… NO    RB    A      0.985 1.00   0         2 141.   56.9  2.85
#>  2  2020     9 1.58e4 Trav… Kelce KC    TE    A      0.996 1.00   0         1  95    38.0 15.6 
#>  3  2020     9 1.68e4 Dava… Adams GB    WR    A      0.978 1.00  -0.002     5  92.2  46.8  9.43
#>  4  2020     9 3.12e6 Dalv… Cook  Min   RB    A      0.941 1.00   0.023     1 148.   50.8  7.85
#>  5  2020     9 3.04e6 Derr… Henry Ten   RB    A      0.988 1.00  -0.005     3 134.   55.0  4.22
#>  6  2020     9 3.14e6 Patr… Maho… KC    QB    A      0.968 1.00   0.001     1 207.   26.0 16.7 
#>  7  2020     9 1.58e4 DeAn… Hopk… Ari   WR    A      0.765 0.999  0.001     9  86.4  46.2 10.6 
#>  8  2020     9 3.12e6 Tyre… Hill  KC    WR    A      0.984 0.999 -0.003     2 107.   19.5 28.0 
#>  9  2020     9 3.05e6 Ezek… Elli… Dal   RB    Q      0.921 0.999 -0.014     7 104.   46.0 11.6 
#> 10  2020     9 1.40e4 Julio Jones Atl   WR    A      0.961 0.999  0.002    20  70.4  31.8 19.8 
#> # … with 1,062 more rows, and 4 more variables: next_wk <dbl>, last_wk <dbl>, last_szn <dbl>,
#> #   this_szn <dbl>

Each player is identified by their unique ID. Sometimes, only those player IDs are given. Team positions like defenses have negative IDs, but information on individual players can be retrieved from the generic ESPN (non-fantasy) API.

player_info(id = 3054850, row = TRUE)
#> # A tibble: 1 x 12
#>        id first last   pos   jersey weight height   age birth_date birth_place debut draft
#>     <dbl> <chr> <chr>  <chr> <chr>   <dbl>  <dbl> <int> <date>     <chr>       <int> <int>
#> 1 3054850 Alvin Kamara RB    41        215     70    25 1995-07-25 Atlanta, GA  2017    67

For your convenience, a table of active players is saved as a data frame.

nfl_players
#> # A tibble: 1,062 x 11
#>         id first   last    pro   pos   jersey weight height   age birth      debut
#>      <int> <chr>   <chr>   <fct> <fct> <chr>   <dbl>  <dbl> <int> <date>     <int>
#>  1 3051392 Ezekiel Elliott Dal   RB    21        228     72    25 1995-07-22  2016
#>  2 3054850 Alvin   Kamara  NO    RB    41        215     70    25 1995-07-25  2017
#>  3 3116593 Dalvin  Cook    Min   RB    33        210     70    25 1995-08-10  2017
#>  4   15795 DeAndre Hopkins Ari   WR    10        212     73    28 1992-06-06  2013
#>  5   15847 Travis  Kelce   KC    TE    87        260     77    30 1989-10-05  2013
#>  6 3116406 Tyreek  Hill    KC    WR    10        185     70    26 1994-03-01  2016
#>  7 3139477 Patrick Mahomes KC    QB    15        230     75    25 1995-09-17  2017
#>  8 3916387 Lamar   Jackson Bal   QB    8         212     74    23 1997-01-07  2018
#>  9   16800 Davante Adams   GB    WR    17        215     73    27 1992-12-24  2014
#> 10 3040151 George  Kittle  SF    TE    85        250     76    26 1993-10-09  2017
#> # … with 1,052 more rows

News on an individual player can also be helpful.

player_news(id = 15847)
#> # A tibble: 15 x 6
#>       id published           type   premium headline                     body                      
#>    <int> <dttm>              <chr>  <lgl>   <chr>                        <chr>                     
#>  1 15847 2020-11-01 22:16:49 Rotow… FALSE   Kelce caught eight of 12 ta… "Kelce's three-yard touch…
#>  2 15847 2020-10-26 01:57:11 Rotow… FALSE   Kelce caught all three of h… "The five-time Pro Bowler…
#>  3 15847 2020-10-20 00:31:47 Rotow… FALSE   Kelce caught five of seven … "Kelce got Kansas City on…
#>  4 15847 2020-10-11 21:34:23 Rotow… FALSE   Kelce brought in eight of 1… "The All-Pro tight end le…
#>  5 15847 2020-10-06 02:42:22 Rotow… FALSE   Kelce caught three of six t… "Kelce again led Kansas C…
#>  6 15847 2020-09-29 04:45:45 Rotow… FALSE   Kelce caught six of seven t… "Kelce led the Chiefs in …
#>  7 15847 2020-09-21 02:08:04 Rotow… FALSE   Kelce caught nine of 14 tar… "Kelce led the team in ta…
#>  8 15847 2020-09-11 04:24:20 Rotow… FALSE   Kelce brought in all six of… "The big tight end was pa…
#>  9 15847 2020-09-08 20:58:01 Rotow… FALSE   Kelce (knee) was a full par… "After being listed as a …
#> 10 15847 2020-09-08 10:32:10 Story  TRUE    Predicting 2020 NFL season … "<p><video1></video1></p>…
#> 11 15847 2020-09-07 23:10:05 Rotow… FALSE   Kelce (knee) was limited in… "Kelce has dealt with the…
#> 12 15847 2020-08-17 15:31:14 Story  FALSE   Inventing 32 props for the … "<p><video1></video1></p>…
#> 13 15847 2020-08-13 19:13:15 Rotow… FALSE   The Chiefs and Kelce agreed… "The exact parameters of …
#> 14 15847 2020-08-13 18:33:26 Rotow… FALSE   The Chiefs and Kelce are cl… "Parameters of the new co…
#> 15 15847 2020-02-03 04:23:02 Rotow… FALSE   Kelce brought in all six of… "Kelce's reception tally …

ESPN analysts publish weekly and preseason outlooks on most players.

outlooks <- player_outlook()
nrow(outlooks)

1 3978

cat(paste(">", outlooks$outlook[1]))

Kamara is coming off an up-and-down 2019 campaign, but the 24-year-old remains the main man in the New Orleans’ backfield. Kamara missed a pair of games but otherwise played a similar role to 2018, handling 12.2 carries and 7.0 targets per game. Kamara ended the season with a YPC above 4.5 and exactly 81 catches for the third consecutive season. A lack of usage near the goal line (7.1 OTD, 6 TDs) limited his fantasy production, though he did finish strongly with four of those scores coming during Weeks 16-17. Kamara should have little trouble pushing for 20 touches per game in the Saints’ Drew Brees-led, high-scoring offense. He remains a solid RB1.

Rosters

For the team rosters in your league, a list of data frames can be returned.

rosters <- team_roster(week = 3)

The elements of this list are named for their team abbreviation.

rosters$KIER
#> # A tibble: 16 x 15
#>     year  week team  slot       id first  last   pro   pos   status  proj score start  rost  change
#>    <int> <int> <fct> <fct>   <int> <chr>  <chr>  <fct> <fct> <chr>  <dbl> <dbl> <dbl> <dbl>   <dbl>
#>  1  2020     3 KIER  QB    4038524 Gardn… Minsh… Jax   QB    O      19.9    9.2  1.74  24.6 -18.3  
#>  2  2020     3 KIER  RB    3054850 Alvin  Kamara NO    RB    A      17.1   31.7 98.5  100.    0    
#>  3  2020     3 KIER  RB    4242335 Jonat… Taylor Ind   RB    A      15.3   12.2 56.4   96.3  -0.942
#>  4  2020     3 KIER  WR      15795 DeAnd… Hopki… Ari   WR    A      11.8   13.7 76.5   99.9   0.001
#>  5  2020     3 KIER  WR      16733 Odell  Beckh… Cle   WR    I       8.82   5.9 15.1   39.0 -26.3  
#>  6  2020     3 KIER  TE      15847 Travis Kelce  KC    TE    A      10.1    8.7 99.6  100.    0    
#>  7  2020     3 KIER  FX    2508176 David  Johns… Hou   RB    A      11.6   10.6 65.5   96.6  -0.119
#>  8  2020     3 KIER  DS     -16023 Steel… D/ST   Pit   DS    A       7.50   7.5 89.8   99.2   2.02 
#>  9  2020     3 KIER  PK      14993 Greg   Zuerl… Dal   PK    A       7.91   9   46.1   51.2  -9.48 
#> 10  2020     3 KIER  BE       2580 Drew   Brees  NO    QB    Q      17.9   23.5 29.6   76.0  -0.382
#> 11  2020     3 KIER  BE    2977187 Cooper Kupp   LAR   WR    A       8.37  16.7 28.2   96.0  -0.362
#> 12  2020     3 KIER  BE    4035538 David  Montg… Chi   RB    A       9.32   5.4 73.6   95.0   0.091
#> 13  2020     3 KIER  BE    3912550 Ronald Jones… TB    RB    A       7.69   7.3 59.3   93.5  -1.67 
#> 14  2020     3 KIER  BE      15072 Marvin Jones… Det   WR    A       8.90   5.1 42.0   79.0  22.3  
#> 15  2020     3 KIER  BE    3025433 Mike   Davis  Car   RB    A       9.32  15.1 28.9   81.5 -16.8  
#> 16  2020     3 KIER  IR    3126486 Deebo  Samuel SF    WR    O       0      0    2.42  61.8 -10.5

We can easily identify the current starting roster, dropping bench players and those on injury reserve.

start_roster(rosters$KIER)
#> # A tibble: 9 x 15
#>    year  week team  slot       id first  last    pro   pos   status  proj score start  rost  change
#>   <int> <int> <fct> <fct>   <int> <chr>  <chr>   <fct> <fct> <chr>  <dbl> <dbl> <dbl> <dbl>   <dbl>
#> 1  2020     3 KIER  QB    4038524 Gardn… Minshe… Jax   QB    O      19.9    9.2  1.74  24.6 -18.3  
#> 2  2020     3 KIER  RB    3054850 Alvin  Kamara  NO    RB    A      17.1   31.7 98.5  100.    0    
#> 3  2020     3 KIER  RB    4242335 Jonat… Taylor  Ind   RB    A      15.3   12.2 56.4   96.3  -0.942
#> 4  2020     3 KIER  WR      15795 DeAnd… Hopkins Ari   WR    A      11.8   13.7 76.5   99.9   0.001
#> 5  2020     3 KIER  WR      16733 Odell  Beckha… Cle   WR    I       8.82   5.9 15.1   39.0 -26.3  
#> 6  2020     3 KIER  TE      15847 Travis Kelce   KC    TE    A      10.1    8.7 99.6  100.    0    
#> 7  2020     3 KIER  FX    2508176 David  Johnson Hou   RB    A      11.6   10.6 65.5   96.6  -0.119
#> 8  2020     3 KIER  DS     -16023 Steel… D/ST    Pit   DS    A       7.50   7.5 89.8   99.2   2.02 
#> 9  2020     3 KIER  PK      14993 Greg   Zuerle… Dal   PK    A       7.91   9   46.1   51.2  -9.48

We can also easily filter for the starting roster that has the highest projected or past score. The score total for that roster can also be easily summed.

(best <- best_roster(rosters$KIER))
#> # A tibble: 9 x 15
#>    year  week team  slot       id first   last   pro   pos   status  proj score start  rost  change
#>   <int> <int> <fct> <fct>   <int> <chr>   <chr>  <fct> <fct> <chr>  <dbl> <dbl> <dbl> <dbl>   <dbl>
#> 1  2020     3 KIER  QB       2580 Drew    Brees  NO    QB    Q      17.9   23.5  29.6  76.0  -0.382
#> 2  2020     3 KIER  RB    3054850 Alvin   Kamara NO    RB    A      17.1   31.7  98.5 100.    0    
#> 3  2020     3 KIER  RB    3025433 Mike    Davis  Car   RB    A       9.32  15.1  28.9  81.5 -16.8  
#> 4  2020     3 KIER  WR    2977187 Cooper  Kupp   LAR   WR    A       8.37  16.7  28.2  96.0  -0.362
#> 5  2020     3 KIER  WR      15795 DeAndre Hopki… Ari   WR    A      11.8   13.7  76.5  99.9   0.001
#> 6  2020     3 KIER  TE      15847 Travis  Kelce  KC    TE    A      10.1    8.7  99.6 100.    0    
#> 7  2020     3 KIER  FX    4242335 Jonath… Taylor Ind   RB    A      15.3   12.2  56.4  96.3  -0.942
#> 8  2020     3 KIER  DS     -16023 Steele… D/ST   Pit   DS    A       7.50   7.5  89.8  99.2   2.02 
#> 9  2020     3 KIER  PK      14993 Greg    Zuerl… Dal   PK    A       7.91   9    46.1  51.2  -9.48
roster_score(best)
#> [1] 138.12

Players on a roster can also be compared against their professional schedule.

The 2020 NFL schedule is saved as the nfl_schedule table. This table might be out of date due to rescheduled games. The current schedule can be returned by pro_schedule(). The table also indicates if the games have started yet.

(sched <- ffl_merge(
  x = rosters$KIER[, 1:9], 
  y = pro_schedule()
))
#> # A tibble: 16 x 13
#>     year  week team  slot       id first  last   pro   pos   opp   home  kickoff             future
#>    <int> <int> <fct> <fct>   <int> <chr>  <chr>  <fct> <fct> <fct> <lgl> <dttm>              <lgl> 
#>  1  2020     3 KIER  QB    4038524 Gardn… Minsh… Jax   QB    Mia   TRUE  2020-09-24 20:20:00 FALSE 
#>  2  2020     3 KIER  RB    3054850 Alvin  Kamara NO    RB    GB    TRUE  2020-09-27 20:20:00 FALSE 
#>  3  2020     3 KIER  BE       2580 Drew   Brees  NO    QB    GB    TRUE  2020-09-27 20:20:00 FALSE 
#>  4  2020     3 KIER  RB    4242335 Jonat… Taylor Ind   RB    NYJ   TRUE  2020-09-27 16:05:00 FALSE 
#>  5  2020     3 KIER  WR      15795 DeAnd… Hopki… Ari   WR    Det   TRUE  2020-09-27 16:25:00 FALSE 
#>  6  2020     3 KIER  WR      16733 Odell  Beckh… Cle   WR    Wsh   TRUE  2020-09-27 13:00:00 FALSE 
#>  7  2020     3 KIER  TE      15847 Travis Kelce  KC    TE    Bal   FALSE 2020-09-28 20:15:00 FALSE 
#>  8  2020     3 KIER  FX    2508176 David  Johns… Hou   RB    Pit   FALSE 2020-09-27 13:00:00 FALSE 
#>  9  2020     3 KIER  DS     -16023 Steel… D/ST   Pit   DS    Hou   TRUE  2020-09-27 13:00:00 FALSE 
#> 10  2020     3 KIER  PK      14993 Greg   Zuerl… Dal   PK    Sea   FALSE 2020-09-27 16:25:00 FALSE 
#> 11  2020     3 KIER  BE    2977187 Cooper Kupp   LAR   WR    Buf   FALSE 2020-09-27 13:00:00 FALSE 
#> 12  2020     3 KIER  BE    4035538 David  Montg… Chi   RB    Atl   FALSE 2020-09-27 13:00:00 FALSE 
#> 13  2020     3 KIER  BE    3912550 Ronald Jones… TB    RB    Den   FALSE 2020-09-27 16:25:00 FALSE 
#> 14  2020     3 KIER  BE      15072 Marvin Jones… Det   WR    Ari   FALSE 2020-09-27 16:25:00 FALSE 
#> 15  2020     3 KIER  BE    3025433 Mike   Davis  Car   RB    LAC   FALSE 2020-09-27 16:05:00 FALSE 
#> 16  2020     3 KIER  IR    3126486 Deebo  Samuel SF    WR    NYG   FALSE 2020-09-27 13:00:00 FALSE

The opponent teams for each player are ranked by the average points scored against them by each position. The lower the rank, the more points that position scores against the opponent team.

ffl_merge(
  x = sched[, 6:10], 
  y = opponent_ranks(), 
  by = c("pos", "opp" = "pro")
)
#> # A tibble: 15 x 7
#>    first    last        pro   pos   opp    rank    avg
#>    <chr>    <chr>       <fct> <fct> <fct> <int>  <dbl>
#>  1 Gardner  Minshew II  Jax   QB    Mia       3 22.4  
#>  2 Alvin    Kamara      NO    RB    GB       29 15.0  
#>  3 Drew     Brees       NO    QB    GB        5 21.8  
#>  4 Jonathan Taylor      Ind   RB    NYJ      30 14.3  
#>  5 DeAndre  Hopkins     Ari   WR    Det      20 23.4  
#>  6 Odell    Beckham Jr. Cle   WR    Wsh       3 29.6  
#>  7 Travis   Kelce       KC    TE    Bal      23  6.44 
#>  8 David    Johnson     Hou   RB    Pit       3 26.3  
#>  9 Steelers D/ST        Pit   DS    Hou      24  0.429
#> 10 Cooper   Kupp        LAR   WR    Buf      31 16.2  
#> 11 David    Montgomery  Chi   RB    Atl      19 17.5  
#> 12 Ronald   Jones II    TB    RB    Den      25 15.8  
#> 13 Marvin   Jones Jr.   Det   WR    Ari      14 24.7  
#> 14 Mike     Davis       Car   RB    LAC       5 23.1  
#> 15 Deebo    Samuel      SF    WR    NYG      23 21.7

Transactions

If you’re interested in how the players on a roster were acquired you look at either the acquisition history, draft picks, or league roster moves.

Every roster identifies players by acquisition method.

player_acquire()[[5]]
#> # A tibble: 17 x 11
#>     year  week team  slot       id first      last       pro   pos   method date               
#>    <int> <int> <fct> <fct>   <int> <chr>      <chr>      <fct> <fct> <chr>  <dttm>             
#>  1  2020     9 KIER  QB      14876 Ryan       Tannehill  Ten   QB    ADD    2020-10-21 12:00:34
#>  2  2020     9 KIER  RB    3054850 Alvin      Kamara     NO    RB    DRAFT  2020-09-06 22:17:42
#>  3  2020     9 KIER  RB    2508176 David      Johnson    Hou   RB    DRAFT  2020-09-06 22:17:42
#>  4  2020     9 KIER  WR      15795 DeAndre    Hopkins    Ari   WR    DRAFT  2020-09-06 22:17:42
#>  5  2020     9 KIER  WR    3042778 Corey      Davis      Ten   WR    ADD    2020-11-05 12:00:09
#>  6  2020     9 KIER  TE      15847 Travis     Kelce      KC    TE    DRAFT  2020-09-06 22:17:42
#>  7  2020     9 KIER  FX    4035538 David      Montgomery Chi   RB    DRAFT  2020-09-06 22:17:42
#>  8  2020     9 KIER  DS     -16028 Washington D/ST       Wsh   DS    ADD    2020-11-04 12:00:08
#>  9  2020     9 KIER  PK    3124084 Joey       Slye       Car   PK    ADD    2020-10-28 12:00:26
#> 10  2020     9 KIER  BE    2977187 Cooper     Kupp       LAR   WR    DRAFT  2020-09-06 22:17:42
#> 11  2020     9 KIER  BE    4242335 Jonathan   Taylor     Ind   RB    DRAFT  2020-09-06 22:17:42
#> 12  2020     9 KIER  BE    3912550 Ronald     Jones II   TB    RB    DRAFT  2020-09-06 22:17:42
#> 13  2020     9 KIER  BE    4038524 Gardner    Minshew II Jax   QB    ADD    2020-09-23 11:00:09
#> 14  2020     9 KIER  BE    3025433 Mike       Davis      Car   RB    ADD    2020-09-23 11:00:09
#> 15  2020     9 KIER  BE    3139522 Travis     Fulgham    Phi   WR    ADD    2020-10-21 12:00:34
#> 16  2020     9 KIER  BE      13983 A.J.       Green      Cin   WR    ADD    2020-11-01 12:00:09
#> 17  2020     9 KIER  IR    3886818 Myles      Gaskin     Mia   RB    ADD    2020-09-30 11:01:14

Roster moves are any waiver add, lineup change, or trade. Roster moves only identify players by their ID, so we will merge with the players table. The ffl_merge() function uses merge() to return a tibble of combined columns and rows in their same order.

ffl_merge(
  x = roster_moves()[, 7:14], 
  y = nfl_players[, 1:3]
)
#> # A tibble: 77 x 10
#>    date                 team from_slot from_team      id to_slot to_team move   first   last    
#>    <dttm>              <int> <fct>         <int>   <int> <fct>     <int> <chr>  <chr>   <chr>   
#>  1 2020-11-03 14:20:11     6 RB               NA 3025433 BE           NA LINEUP Mike    Davis   
#>  2 2020-11-03 14:20:11     6 BE               NA 2508176 RB           NA LINEUP David   Johnson 
#>  3 2020-11-03 13:40:01     6 BE               NA   15795 WR           NA LINEUP DeAndre Hopkins 
#>  4 2020-11-03 13:40:01     6 WR               NA 3139522 BE           NA LINEUP Travis  Fulgham 
#>  5 2020-11-05 12:02:46     6 BE               NA 3042778 WR           NA LINEUP Corey   Davis   
#>  6 2020-11-05 12:00:09     6 <NA>             NA 3042778 <NA>          6 ADD    Corey   Davis   
#>  7 2020-11-03 09:28:14     4 BE               NA 4052042 RB           NA LINEUP James   Robinson
#>  8 2020-11-03 09:28:14     4 RB               NA 3928925 BE           NA LINEUP JaMycal Hasty   
#>  9 2020-11-03 09:28:14     4 BE               NA 3119195 FX           NA LINEUP Chase   Edmonds 
#> 10 2020-11-04 09:09:41     4 BE               NA 3932905 WR           NA LINEUP Diontae Johnson 
#> # … with 67 more rows

We can also get the entire history of the draft, either snake or auction.

ffl_merge(
  x = draft_picks(), 
  y = nfl_players[, 1:3]
)
#> # A tibble: 128 x 9
#>     year type     pick nominator  team   bid      id first     last          
#>    <int> <chr>   <int>     <int> <int> <int>   <int> <chr>     <chr>         
#>  1  2020 AUCTION     1         8     4    57 3929630 Saquon    Barkley       
#>  2  2020 AUCTION     2         3     8    33 3916387 Lamar     Jackson       
#>  3  2020 AUCTION     3        10     3    23 3120348 JuJu      Smith-Schuster
#>  4  2020 AUCTION     4        11     1     3    2330 Tom       Brady         
#>  5  2020 AUCTION     5         5     1    32 4045163 Miles     Sanders       
#>  6  2020 AUCTION     6         4     8    81 3117251 Christian McCaffrey     
#>  7  2020 AUCTION     7         1     5    45 4047365 Josh      Jacobs        
#>  8  2020 AUCTION     8         6    10     7   13229 Rob       Gronkowski    
#>  9  2020 AUCTION     9         8    10    52 3043078 Derrick   Henry         
#> 10  2020 AUCTION    10         3    11    32   16737 Mike      Evans         
#> # … with 118 more rows

A summary of transactions and moves is also available.

moves_summary()
#> # A tibble: 8 x 11
#>    year  week  team abbrev waiver spent acquisitions drops activated reserved trades
#>   <int> <int> <int> <fct>   <int> <int>        <int> <int>     <int>    <int>  <int>
#> 1  2020     9     1 AGUS        3    46           13    13        39        0      0
#> 2  2020     9     3 PEPE        1    34            9     8        38        2      0
#> 3  2020     9     4 BILL        4    91           15    14        52        4      0
#> 4  2020     9     5 CART        6    48           11    11        34        0      0
#> 5  2020     9     6 KIER        7    70           17    16        40        2      0
#> 6  2020     9     8 CORE        8    43           15    15        51        1      0
#> 7  2020     9    10 NICK        5    44           18    17        40        3      0
#> 8  2020     9    11 KYLE        2    57           11    10        42        1      0

Scores

Past team scores are found in the tidy tibble by matchup period.

match_scores()
#> # A tibble: 64 x 9
#>     year match week   team abbrev home  score winner power
#>    <int> <int> <fct> <int> <fct>  <lgl> <dbl> <lgl>  <dbl>
#>  1  2020     1 1         3 PEPE   TRUE  103.  TRUE       4
#>  2  2020     1 1         1 AGUS   FALSE  68.5 FALSE      0
#>  3  2020     2 1        10 NICK   TRUE   86.0 FALSE      1
#>  4  2020     2 1         4 BILL   FALSE 134.  TRUE       6
#>  5  2020     3 1         5 CART   TRUE  149.  TRUE       7
#>  6  2020     3 1        11 KYLE   FALSE  94.7 FALSE      2
#>  7  2020     4 1         8 CORE   TRUE  119.  TRUE       5
#>  8  2020     4 1         6 KIER   FALSE  99.7 FALSE      3
#>  9  2020     5 2         1 AGUS   TRUE  144.  TRUE       7
#> 10  2020     5 2         4 BILL   FALSE 110.  FALSE      2
#> # … with 54 more rows

These scores are only for matches played. We can also determine future matches.

match_schedule()
#> # A tibble: 96 x 6
#>     year  week match team  opp   home 
#>    <int> <int> <int> <fct> <fct> <lgl>
#>  1  2020     1     1 PEPE  AGUS  TRUE 
#>  2  2020     1     1 AGUS  PEPE  FALSE
#>  3  2020     1     2 NICK  BILL  TRUE 
#>  4  2020     1     2 BILL  NICK  FALSE
#>  5  2020     1     3 CART  KYLE  TRUE 
#>  6  2020     1     3 KYLE  CART  FALSE
#>  7  2020     1     4 CORE  KIER  TRUE 
#>  8  2020     1     4 KIER  CORE  FALSE
#>  9  2020     2     5 AGUS  BILL  TRUE 
#> 10  2020     2     5 BILL  AGUS  FALSE
#> # … with 86 more rows

If a matchup period is currently ongoing, the live score and projection can also be found.

live_scoring()
#> # A tibble: 8 x 6
#>    week match team  score  proj    line
#> * <int> <int> <fct> <dbl> <dbl>   <dbl>
#> 1     9    33 BILL    0   116.   13.8  
#> 2     9    33 AGUS    7.9 102.  -13.8  
#> 3     9    34 PEPE    0.5  90.8 -14.0  
#> 4     9    34 KYLE    0   105.   14.0  
#> 5     9    35 NICK    0   102.   -0.224
#> 6     9    35 KIER    0   102.    0.224
#> 7     9    36 CART   28   107.   11.0  
#> 8     9    36 CORE    0    96.0 -11.0

It’s worth noting that matchups and weeks are different units of time. For this league, for example, regular season matchups last one week and playoff matches last two.

schedule_settings()
#> $year
#> [1] 2020
#> 
#> $divisions
#> # A tibble: 1 x 3
#>      id name   size
#>   <int> <chr> <int>
#> 1     0 East      8
#> 
#> $match_count
#> [1] 12
#> 
#> $match_length
#> [1] 1
#> 
#> $match_sched
#> # A tibble: 16 x 2
#>     week period
#>    <int> <chr> 
#>  1     1 1     
#>  2     2 2     
#>  3     3 3     
#>  4     4 4     
#>  5     5 5     
#>  6     6 6     
#>  7     7 7     
#>  8     8 8     
#>  9     9 9     
#> 10    10 10    
#> 11    11 11    
#> 12    12 12    
#> 13    13 13    
#> 14    14 13    
#> 15    16 14    
#> 16    15 14    
#> 
#> $period_type
#> [1] 1
#> 
#> $playoff_length
#> [1] 2
#> 
#> $seed_rule
#> [1] "TOTAL_POINTS_SCORED"
#> 
#> $playoff_size
#> [1] 4

If you want to return scores by week, use a different function. These functions also return “power wins” which are the total number of wins a team would get if they played every other team in the league; the lowest score gets zero power wins and the highest gets one less than the number of teams.

week_scores()
#> # A tibble: 64 x 8
#>     year match  week  team abbrev home  score power
#>    <int> <int> <dbl> <int> <fct>  <lgl> <dbl> <dbl>
#>  1  2020     1     1     3 PEPE   TRUE  103.      4
#>  2  2020     1     1     1 AGUS   FALSE  68.5     0
#>  3  2020     2     1    10 NICK   TRUE   86.0     1
#>  4  2020     2     1     4 BILL   FALSE 134.      6
#>  5  2020     3     1     5 CART   TRUE  149.      7
#>  6  2020     3     1    11 KYLE   FALSE  94.7     2
#>  7  2020     4     1     8 CORE   TRUE  119.      5
#>  8  2020     4     1     6 KIER   FALSE  99.7     3
#>  9  2020     5     2     1 AGUS   TRUE  144.      7
#> 10  2020     5     2     4 BILL   FALSE 110.      2
#> # … with 54 more rows

A summary of scores and wins is also available.

score_summary()
#> # A tibble: 8 x 16
#>    year  week  team abbrev draft current  seed final  back losses  ties  wins percentage against
#>   <int> <int> <int> <fct>  <int>   <int> <int> <int> <dbl>  <int> <int> <int>      <dbl>   <dbl>
#> 1  2020     9     1 AGUS       1       2     2    NA     0      2     0     6      0.75     781.
#> 2  2020     9     3 PEPE       7       7     5    NA     2      4     0     4      0.5      725.
#> 3  2020     9     4 BILL       8       1     1    NA     0      2     0     6      0.75     793.
#> 4  2020     9     5 CART       5       3     3    NA     2      4     0     4      0.5      790.
#> 5  2020     9     6 KIER       4       6     7    NA     3      5     0     3      0.375    844.
#> 6  2020     9     8 CORE       6       8     8    NA     4      6     0     2      0.25     913.
#> 7  2020     9    10 NICK       3       5     6    NA     3      5     0     3      0.375    837.
#> 8  2020     9    11 KYLE       2       4     4    NA     2      4     0     4      0.5      870.
#> # … with 2 more variables: points <dbl>, streak <dbl>

Historical

Most functions have an old argument that can be used to specify access to the historical endpoint of the API. If the recent data is usually returned as a dataframe, like rosters, then a list of dataframes is returned instead; if the recent data is a list, then a single dataframe is returned instead.

past <- week_scores(old = TRUE)
names(past) <- 2015:2019
str(past, max.level = 1)
#> List of 5
#>  $ 2015: tibble [136 × 8] (S3: tbl_df/tbl/data.frame)
#>  $ 2016: tibble [170 × 8] (S3: tbl_df/tbl/data.frame)
#>  $ 2017: tibble [160 × 8] (S3: tbl_df/tbl/data.frame)
#>  $ 2018: tibble [160 × 8] (S3: tbl_df/tbl/data.frame)
#>  $ 2019: tibble [128 × 8] (S3: tbl_df/tbl/data.frame)
str(league_info())
#> List of 6
#>  $ year  : int 2020
#>  $ name  : chr "Gambling Addicts Anonymous"
#>  $ id    : int 252353
#>  $ public: logi TRUE
#>  $ size  : int 8
#>  $ length: int 16
league_info(old = TRUE)
#> # A tibble: 5 x 6
#>    year name                           id public  size length
#>   <int> <chr>                       <int> <lgl>  <int>  <int>
#> 1  2015 Gambling Addicts Anonymous 252353 FALSE      8     17
#> 2  2016 Gambling Addicts Anonymous 252353 FALSE     10     17
#> 3  2017 Gambling Addicts Anonymous 252353 FALSE     10     16
#> 4  2018 Gambling Addicts Anonymous 252353 FALSE     10     16
#> 5  2019 Gambling Addicts Anonymous 252353 TRUE       8     16