fantasy-football

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

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     6 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 6
#>  $ 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] 6

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] 7

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]> BIG TRUZZZ              
#> 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,065 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     6 3.05e6 Ezek… Elli… Dal   RB    A      0.998 1.00  -0.001     5  87.7  57.7  2.97
#>  2  2020     6 1.58e4 Trav… Kelce KC    TE    A      0.995 1.00  -0.001     1  58.5  29.2 21.3 
#>  3  2020     6 3.14e6 Patr… Maho… KC    QB    A      0.976 0.999  0.002     2 138.   19.6 20.2 
#>  4  2020     6 1.58e4 DeAn… Hopk… Ari   WR    A      0.996 0.999 -0.001     8  64.8  40.2 12.2 
#>  5  2020     6 3.12e6 Tyre… Hill  KC    WR    A      0.990 0.999 -0.001     6  71.3  29.8 20.7 
#>  6  2020     6 3.04e6 Derr… Henry Ten   RB    A      0.973 0.999  0.005     2 103.   45.6  9.60
#>  7  2020     6 3.05e6 Alvin Kama… NO    RB    A      0.157 0.999 -0.02      1 110.   60.2  3.27
#>  8  2020     6 1.68e4 Dava… Adams GB    WR    A      0.929 0.999  0.043    43  37.3  44.2 10.4 
#>  9  2020     6 3.04e6 Geor… Kitt… SF    TE    A      0.968 0.999 -0.006     4  51.7  29.1 25.2 
#> 10  2020     6 3.92e6 Lamar Jack… Bal   QB    A      0.912 0.999 -0.011     7 126    20.7 26.6 
#> # … with 1,055 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: 13 x 6
#>       id published           type   premium headline                     body                      
#>    <int> <dttm>              <chr>  <lgl>   <chr>                        <chr>                     
#>  1 15847 2020-10-11 21:34:23 Rotow… FALSE   Kelce brought in eight of 1… "The All-Pro tight end le…
#>  2 15847 2020-10-06 02:42:22 Rotow… FALSE   Kelce caught three of six t… "Kelce again led Kansas C…
#>  3 15847 2020-09-29 04:45:45 Rotow… FALSE   Kelce caught six of seven t… "Kelce led the Chiefs in …
#>  4 15847 2020-09-21 02:08:04 Rotow… FALSE   Kelce caught nine of 14 tar… "Kelce led the team in ta…
#>  5 15847 2020-09-11 04:24:20 Rotow… FALSE   Kelce brought in all six of… "The big tight end was pa…
#>  6 15847 2020-09-08 20:58:01 Rotow… FALSE   Kelce (knee) was a full par… "After being listed as a …
#>  7 15847 2020-09-08 10:32:10 Story  TRUE    Predicting 2020 NFL season … "<p><video1></video1></p>…
#>  8 15847 2020-09-07 23:10:05 Rotow… FALSE   Kelce (knee) was limited in… "Kelce has dealt with the…
#>  9 15847 2020-08-17 15:31:14 Story  FALSE   Inventing 32 props for the … "<p><video1></video1></p>…
#> 10 15847 2020-08-13 19:13:15 Rotow… FALSE   The Chiefs and Kelce agreed… "The exact parameters of …
#> 11 15847 2020-08-13 18:33:26 Rotow… FALSE   The Chiefs and Kelce are cl… "Parameters of the new co…
#> 12 15847 2020-02-03 04:23:02 Rotow… FALSE   Kelce brought in all six of… "Kelce's reception tally …
#> 13 15847 2020-01-24 22:43:49 Rotow… FALSE   Kelce (knee) doesn't have a… "During the first week of…

ESPN analysts publish weekly and preseason outlooks on most players.

outlooks <- player_outlook()
nrow(outlooks)

1 3052

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

Elliott returns as the clear feature back in Dallas. Since entering the league in 2016, the Ohio State product leads the NFL in carries (1,169) and rushing yards (5,405), and sits second in rushing touchdowns (40). Elliott obviously plays a substantial role as a ball carrier – and his goal-line work increased last season – but it was a bit surprising to see his targets fall from 6.3 to 4.4 per game last season. Of course, Elliott’s role still allowed him a top-3 finish in touches, yards and fantasy points. The 25-year-old is positioned for a similar role in 2020 behind a strong offensive line and should be off the board in the middle of the first round of drafts.

Rosters

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

rosters <- team_roster()

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     6 KIER  QB    4038524 Gardn… Minsh… Jax   QB    A      19.3   17.1 34.1   60.6   4.54 
#>  2  2020     6 KIER  RB    3025433 Mike   Davis  Car   RB    A      14.7    9.5 95.2   97.4   2.66 
#>  3  2020     6 KIER  RB    3886818 Myles  Gaskin Mia   RB    A      13.2   12.6 76.0   87.9   9.33 
#>  4  2020     6 KIER  WR      15795 DeAnd… Hopki… Ari   WR    A      12.2   NA   99.6   99.9  -0.001
#>  5  2020     6 KIER  WR      16733 Odell  Beckh… Cle   WR    A      10.6    2.5 84.0   98.6  -0.034
#>  6  2020     6 KIER  TE      15847 Travis Kelce  KC    TE    A      11.4   NA   99.5  100.   -0.001
#>  7  2020     6 KIER  FX    4035538 David  Montg… Chi   RB    A      12.9    9.7 70.4   92.9   2.46 
#>  8  2020     6 KIER  DS     -16014 Rams   D/ST   LAR   DS    A       5.12  -6   74.7   86.3  -0.064
#>  9  2020     6 KIER  PK    3915165 Rodri… Blank… Ind   PK    A       8.67   8   78.9   83.5   0.157
#> 10  2020     6 KIER  BE    3054850 Alvin  Kamara NO    RB    A       0     NA   15.7   99.9  -0.02 
#> 11  2020     6 KIER  BE    2508176 David  Johns… Hou   RB    A      12.0   12.9 74.6   96.3  -0.788
#> 12  2020     6 KIER  BE    2977187 Cooper Kupp   LAR   WR    A       9.16   1.1 78.6   97.2  -0.387
#> 13  2020     6 KIER  BE    4242335 Jonat… Taylor Ind   RB    A      12.4   11.5 79.6   97.3  -0.42 
#> 14  2020     6 KIER  BE    3912550 Ronald Jones… TB    RB    A      11.7   24.1 57.9   90.3   0.63 
#> 15  2020     6 KIER  BE    3915511 Joe    Burrow Cin   QB    A      14.2   16.7  9.45  49.0 -18.6  
#> 16  2020     6 KIER  BE      15835 Zach   Ertz   Phi   TE    Q       5.88   3.3 77.0   96.9  -2.02

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     6 KIER  QB    4038524 Gardn… Minshew… Jax   QB    A      19.3   17.1  34.1  60.6  4.54 
#> 2  2020     6 KIER  RB    3025433 Mike   Davis    Car   RB    A      14.7    9.5  95.2  97.4  2.66 
#> 3  2020     6 KIER  RB    3886818 Myles  Gaskin   Mia   RB    A      13.2   12.6  76.0  87.9  9.33 
#> 4  2020     6 KIER  WR      15795 DeAnd… Hopkins  Ari   WR    A      12.2   NA    99.6  99.9 -0.001
#> 5  2020     6 KIER  WR      16733 Odell  Beckham… Cle   WR    A      10.6    2.5  84.0  98.6 -0.034
#> 6  2020     6 KIER  TE      15847 Travis Kelce    KC    TE    A      11.4   NA    99.5 100.  -0.001
#> 7  2020     6 KIER  FX    4035538 David  Montgom… Chi   RB    A      12.9    9.7  70.4  92.9  2.46 
#> 8  2020     6 KIER  DS     -16014 Rams   D/ST     LAR   DS    A       5.12  -6    74.7  86.3 -0.064
#> 9  2020     6 KIER  PK    3915165 Rodri… Blanken… Ind   PK    A       8.67   8    78.9  83.5  0.157

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     6 KIER  QB    4038524 Gardn… Minshew… Jax   QB    A      19.3   17.1  34.1  60.6  4.54 
#> 2  2020     6 KIER  RB    3912550 Ronald Jones II TB    RB    A      11.7   24.1  57.9  90.3  0.63 
#> 3  2020     6 KIER  RB    2508176 David  Johnson  Hou   RB    A      12.0   12.9  74.6  96.3 -0.788
#> 4  2020     6 KIER  WR      16733 Odell  Beckham… Cle   WR    A      10.6    2.5  84.0  98.6 -0.034
#> 5  2020     6 KIER  WR    2977187 Cooper Kupp     LAR   WR    A       9.16   1.1  78.6  97.2 -0.387
#> 6  2020     6 KIER  TE      15835 Zach   Ertz     Phi   TE    Q       5.88   3.3  77.0  96.9 -2.02 
#> 7  2020     6 KIER  FX    3886818 Myles  Gaskin   Mia   RB    A      13.2   12.6  76.0  87.9  9.33 
#> 8  2020     6 KIER  DS     -16014 Rams   D/ST     LAR   DS    A       5.12  -6    74.7  86.3 -0.064
#> 9  2020     6 KIER  PK    3915165 Rodri… Blanken… Ind   PK    A       8.67   8    78.9  83.5  0.157
roster_score(best)
#> [1] 75.62

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: 15 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     6 KIER  QB    4038524 Gardn… Minsh… Jax   QB    Det   TRUE  2020-10-18 13:00:00 FALSE 
#>  2  2020     6 KIER  RB    3025433 Mike   Davis  Car   RB    Chi   TRUE  2020-10-18 13:00:00 FALSE 
#>  3  2020     6 KIER  RB    3886818 Myles  Gaskin Mia   RB    NYJ   TRUE  2020-10-18 16:05:00 FALSE 
#>  4  2020     6 KIER  WR      15795 DeAnd… Hopki… Ari   WR    Dal   FALSE 2020-10-19 20:15:00 TRUE  
#>  5  2020     6 KIER  WR      16733 Odell  Beckh… Cle   WR    Pit   FALSE 2020-10-18 13:00:00 FALSE 
#>  6  2020     6 KIER  TE      15847 Travis Kelce  KC    TE    Buf   FALSE 2020-10-19 17:00:00 TRUE  
#>  7  2020     6 KIER  FX    4035538 David  Montg… Chi   RB    Car   FALSE 2020-10-18 13:00:00 FALSE 
#>  8  2020     6 KIER  DS     -16014 Rams   D/ST   LAR   DS    SF    FALSE 2020-10-18 20:20:00 FALSE 
#>  9  2020     6 KIER  BE    2977187 Cooper Kupp   LAR   WR    SF    FALSE 2020-10-18 20:20:00 FALSE 
#> 10  2020     6 KIER  PK    3915165 Rodri… Blank… Ind   PK    Cin   TRUE  2020-10-18 13:00:00 FALSE 
#> 11  2020     6 KIER  BE    4242335 Jonat… Taylor Ind   RB    Cin   TRUE  2020-10-18 13:00:00 FALSE 
#> 12  2020     6 KIER  BE    2508176 David  Johns… Hou   RB    Ten   FALSE 2020-10-18 13:00:00 FALSE 
#> 13  2020     6 KIER  BE    3912550 Ronald Jones… TB    RB    GB    TRUE  2020-10-18 16:25:00 FALSE 
#> 14  2020     6 KIER  BE    3915511 Joe    Burrow Cin   QB    Ind   FALSE 2020-10-18 13:00:00 FALSE 
#> 15  2020     6 KIER  BE      15835 Zach   Ertz   Phi   TE    Bal   TRUE  2020-10-18 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: 14 x 7
#>    first    last        pro   pos   opp    rank   avg
#>    <chr>    <chr>       <fct> <fct> <fct> <int> <dbl>
#>  1 Gardner  Minshew II  Jax   QB    Det       8 21.1 
#>  2 Mike     Davis       Car   RB    Chi       3 27.4 
#>  3 Myles    Gaskin      Mia   RB    NYJ       7 24.1 
#>  4 DeAndre  Hopkins     Ari   WR    Dal      28 18.5 
#>  5 Odell    Beckham Jr. Cle   WR    Pit       3 31.1 
#>  6 Travis   Kelce       KC    TE    Buf      13  8.04
#>  7 David    Montgomery  Chi   RB    Car      19 17.8 
#>  8 Rams     D/ST        LAR   DS    SF       27 -0.4 
#>  9 Cooper   Kupp        LAR   WR    SF       32 14.6 
#> 10 Jonathan Taylor      Ind   RB    Cin      30 13.5 
#> 11 David    Johnson     Hou   RB    Ten       6 24.2 
#> 12 Ronald   Jones II    TB    RB    GB       25 15.5 
#> 13 Joe      Burrow      Cin   QB    Ind      27 16.2 
#> 14 Zach     Ertz        Phi   TE    Bal       5 12.2

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: 16 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     6 KIER  QB    4038524 Gardner  Minshew II  Jax   QB    ADD    2020-09-23 11:00:09
#>  2  2020     6 KIER  RB    3025433 Mike     Davis       Car   RB    ADD    2020-09-23 11:00:09
#>  3  2020     6 KIER  RB    3886818 Myles    Gaskin      Mia   RB    ADD    2020-09-30 11:01:14
#>  4  2020     6 KIER  WR      15795 DeAndre  Hopkins     Ari   WR    DRAFT  2020-09-06 22:17:42
#>  5  2020     6 KIER  WR      16733 Odell    Beckham Jr. Cle   WR    DRAFT  2020-09-06 22:17:42
#>  6  2020     6 KIER  TE      15847 Travis   Kelce       KC    TE    DRAFT  2020-09-06 22:17:42
#>  7  2020     6 KIER  FX    4035538 David    Montgomery  Chi   RB    DRAFT  2020-09-06 22:17:42
#>  8  2020     6 KIER  DS     -16014 Rams     D/ST        LAR   DS    ADD    2020-10-02 11:01:43
#>  9  2020     6 KIER  PK    3915165 Rodrigo  Blankenship Ind   PK    ADD    2020-10-07 11:01:36
#> 10  2020     6 KIER  BE    3054850 Alvin    Kamara      NO    RB    DRAFT  2020-09-06 22:17:42
#> 11  2020     6 KIER  BE    2508176 David    Johnson     Hou   RB    DRAFT  2020-09-06 22:17:42
#> 12  2020     6 KIER  BE    2977187 Cooper   Kupp        LAR   WR    DRAFT  2020-09-06 22:17:42
#> 13  2020     6 KIER  BE    4242335 Jonathan Taylor      Ind   RB    DRAFT  2020-09-06 22:17:42
#> 14  2020     6 KIER  BE    3912550 Ronald   Jones II    TB    RB    DRAFT  2020-09-06 22:17:42
#> 15  2020     6 KIER  BE    3915511 Joe      Burrow      Cin   QB    ADD    2020-10-03 11:00:24
#> 16  2020     6 KIER  BE      15835 Zach     Ertz        Phi   TE    ADD    2020-10-04 11:00:12

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: 102 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-10-14 11:15:56     1 FX               NA 3042519 RB           NA LINEUP Aaron   Jones    
#>  2 2020-10-14 16:13:19     1 RB               NA 3042519 FX           NA LINEUP Aaron   Jones    
#>  3 2020-10-14 11:09:05     1 BE               NA 3042519 FX           NA LINEUP Aaron   Jones    
#>  4 2020-10-14 16:13:21     1 FX               NA 3042519 RB           NA LINEUP Aaron   Jones    
#>  5 2020-10-14 16:13:15     1 FX               NA 4045163 RB           NA LINEUP Miles   Sanders  
#>  6 2020-10-14 16:13:21     1 RB               NA 4045163 FX           NA LINEUP Miles   Sanders  
#>  7 2020-10-14 11:15:56     1 RB               NA 4045163 FX           NA LINEUP Miles   Sanders  
#>  8 2020-10-16 12:00:51     8 <NA>             NA   15072 <NA>          8 ADD    Marvin  Jones Jr.
#>  9 2020-10-16 18:09:01     8 BE               NA   15072 WR           NA LINEUP Marvin  Jones Jr.
#> 10 2020-10-14 12:00:26     8 <NA>              8 4360438 <NA>         NA DROP   Brandon Aiyuk    
#> # … with 92 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     6     1 AGUS        5    35           10    10        25        0      0
#> 2  2020     6     3 PEPE        8    22            5     4        23        2      0
#> 3  2020     6     4 BILL        7    69           10     9        34        3      0
#> 4  2020     6     5 CART        4    42            7     7        22        0      0
#> 5  2020     6     6 KIER        2    29            8     8        18        1      0
#> 6  2020     6     8 CORE        6    41           13    12        34        1      0
#> 7  2020     6    10 NICK        1    32           13    13        29        2      0
#> 8  2020     6    11 KYLE        3    32            7     6        26        1      0

Scores

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

match_scores()
#> # A tibble: 40 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 30 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 5
#>    week match team  score  proj
#>   <int> <int> <fct> <dbl> <dbl>
#> 1     6    21 AGUS   79.3 103. 
#> 2     6    21 CART   57.5  70.0
#> 3     6    22 NICK  131.  139. 
#> 4     6    22 CORE   49.5  68.1
#> 5     6    23 PEPE   21.9  79.5
#> 6     6    23 KIER   53.4  77.1
#> 7     6    24 BILL   86.3  86.3
#> 8     6    24 KYLE   44.5  97.8

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: 40 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 30 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     6     1 AGUS       1       2     3    NA     1      2     0     3        0.6    515.
#> 2  2020     6     3 PEPE       7       6     7    NA     2      3     0     2        0.4    476.
#> 3  2020     6     4 BILL       8       4     2    NA     1      2     0     3        0.6    527.
#> 4  2020     6     5 CART       5       1     1    NA     0      1     0     4        0.8    489.
#> 5  2020     6     6 KIER       4       7     4    NA     2      3     0     2        0.4    597.
#> 6  2020     6     8 CORE       6       8     8    NA     2      3     0     2        0.4    545.
#> 7  2020     6    10 NICK       3       3     6    NA     2      3     0     2        0.4    522.
#> 8  2020     6    11 KYLE       2       5     5    NA     2      3     0     2        0.4    613.
#> # … 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