fantasy-football

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

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    2021 NBA        basketball 2020-11-13 03:00:00 2022-11-13 03:00:00
#> 4 FHL   TRUE    2021 NHL        hockey     2020-11-13 03:00:00 2022-11-13 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    18 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 18
#>  $ 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] 18

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

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]> evermoore .                
#> 4  2020     5 CART   <chr [1]> OG Mudbone’s Yogurt Machine
#> 5  2020     6 KIER   <chr [1]> The Nuklear Option         
#> 6  2020     8 CORE   <chr [1]> THE Jets 😭                
#> 7  2020    10 NICK   <chr [1]> The Silence Of The Lamb    
#> 8  2020    11 KYLE   <chr [1]> Aaron It Out

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 by setting the limit to NULL, which can take some time.

all_players(limit = 5)

For your convenience, a table of all 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

This table also has additional biographical data from the generic (non-fantasy) ESPN API, which uses the same unique player ID.

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

News on an individual player can also be helpful.

player_news(id = 15847)
#> # A tibble: 21 x 6
#>       id published           type   premium headline                     body                      
#>    <int> <dttm>              <chr>  <lgl>   <chr>                        <chr>                     
#>  1 15847 2021-01-04 16:29:14 Story  TRUE    NFL awards 2020: Picks for … "<p><video1></video1></p>…
#>  2 15847 2021-01-03 20:56:55 Rotow… FALSE   Though Kelce is not among K… "In addition to five play…
#>  3 15847 2021-01-01 18:58:07 Rotow… FALSE   Kelce is a candidate to be … "Kelce isn't listed on th…
#>  4 15847 2020-12-31 13:40:37 Story  TRUE    NFL All-Pro Team: Bill Barn… "<p><video1></video1></p>…
#>  5 15847 2020-12-27 21:24:02 Rotow… FALSE   Kelce secured seven of 13 t… "Kelce made NFL history S…
#>  6 15847 2020-12-21 03:27:48 Rotow… FALSE   Kelce caught eight of 12 ta… "He took a shovel pass fr…
#>  7 15847 2020-12-13 21:50:09 Rotow… FALSE   Kelce caught eight of 10 ta… "Kelce's six-yard touchdo…
#>  8 15847 2020-12-07 05:20:08 Rotow… FALSE   Kelce racked up 138 receivi… "The Chiefs were uncharac…
#>  9 15847 2020-11-30 01:13:27 Rotow… FALSE   Kelce brought in all eight … "The veteran was a distan…
#> 10 15847 2020-11-23 06:39:33 Rotow… FALSE   Kelce hauled in eight passe… "Kelce feasted between th…
#> # … with 11 more rows

ESPN analysts publish weekly and preseason outlooks on most players.

outlooks <- player_outlook(limit = 1)
nrow(outlooks)

1 17

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

Adams is back as Aaron Rodgers’ unquestioned No. 1 target – a role that has allowed him to post four consecutive seasons as a top-10 WR in fantasy points per game. Adams handled a career-high 31% target share and was fantasy’s No. 2-scoring WR during the 12 weeks in which he was active last season. He finished as a top-five WR in 42% of those outings, which trailed only Michael Thomas. The only concern here is durability as Adams has missed at least one regular-season game due to injury in each of the past three seasons, including four 2019 absences. We’ll need to dock him slightly for that, but the 27-year-old’s massive usage locks him into the top-end WR1 mix.

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    A      19.9    9.2  1.86  8.93  -1.05 
#>  2  2020     3 KIER  RB    3054850 Alvin  Kamara NO    RB    O      17.1   31.7 65.8  99.8   -0.18 
#>  3  2020     3 KIER  RB    4242335 Jonat… Taylor Ind   RB    A      15.3   12.2 82.6  98.6    0.964
#>  4  2020     3 KIER  WR      15795 DeAnd… Hopki… Ari   WR    A      11.8   13.7 94.2  99.9   -0.019
#>  5  2020     3 KIER  WR      16733 Odell  Beckh… Cle   WR    I       8.82   5.9 13.8  30.4    3.23 
#>  6  2020     3 KIER  TE      15847 Travis Kelce  KC    TE    A      10.1    8.7 62.4  97.3   -2.66 
#>  7  2020     3 KIER  FX    2508176 David  Johns… Hou   RB    A      11.6   10.6 63.2  92.1    0.226
#>  8  2020     3 KIER  DS     -16023 Steel… D/ST   Pit   DS    A       7.50   7.5 74.1  93.4   -3.11 
#>  9  2020     3 KIER  PK      14993 Greg   Zuerl… Dal   PK    A       7.91   9   33.8  41.0    2.72 
#> 10  2020     3 KIER  BE       2580 Drew   Brees  NO    QB    A      17.9   23.5 14.3  53.0   -1.24 
#> 11  2020     3 KIER  BE    2977187 Cooper Kupp   LAR   WR    A       8.37  16.7 50.4  89.1   -7.94 
#> 12  2020     3 KIER  BE    4035538 David  Montg… Chi   RB    A       9.32   5.4 79.8  97.9   -0.123
#> 13  2020     3 KIER  BE    3912550 Ronald Jones… TB    RB    A       7.69   7.3 31.5  87.8    1.12 
#> 14  2020     3 KIER  BE      15072 Marvin Jones… Det   WR    A       8.90   5.1 43.5  83.2   -4.65 
#> 15  2020     3 KIER  BE    3025433 Mike   Davis  Car   RB    O       9.32  15.1 32.5  80.0  -11.8  
#> 16  2020     3 KIER  IR    3126486 Deebo  Samuel SF    WR    O       0      0    6.29 51.3   -4.73

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 Gardner Minshe… Jax   QB    A      19.9    9.2  1.86  8.93 -1.05 
#> 2  2020     3 KIER  RB    3054850 Alvin   Kamara  NO    RB    O      17.1   31.7 65.8  99.8  -0.18 
#> 3  2020     3 KIER  RB    4242335 Jonath… Taylor  Ind   RB    A      15.3   12.2 82.6  98.6   0.964
#> 4  2020     3 KIER  WR      15795 DeAndre Hopkins Ari   WR    A      11.8   13.7 94.2  99.9  -0.019
#> 5  2020     3 KIER  WR      16733 Odell   Beckha… Cle   WR    I       8.82   5.9 13.8  30.4   3.23 
#> 6  2020     3 KIER  TE      15847 Travis  Kelce   KC    TE    A      10.1    8.7 62.4  97.3  -2.66 
#> 7  2020     3 KIER  FX    2508176 David   Johnson Hou   RB    A      11.6   10.6 63.2  92.1   0.226
#> 8  2020     3 KIER  DS     -16023 Steele… D/ST    Pit   DS    A       7.50   7.5 74.1  93.4  -3.11 
#> 9  2020     3 KIER  PK      14993 Greg    Zuerle… Dal   PK    A       7.91   9   33.8  41.0   2.72

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    A      17.9   23.5  14.3  53.0  -1.24 
#> 2  2020     3 KIER  RB    3054850 Alvin   Kamara NO    RB    O      17.1   31.7  65.8  99.8  -0.18 
#> 3  2020     3 KIER  RB    3025433 Mike    Davis  Car   RB    O       9.32  15.1  32.5  80.0 -11.8  
#> 4  2020     3 KIER  WR    2977187 Cooper  Kupp   LAR   WR    A       8.37  16.7  50.4  89.1  -7.94 
#> 5  2020     3 KIER  WR      15795 DeAndre Hopki… Ari   WR    A      11.8   13.7  94.2  99.9  -0.019
#> 6  2020     3 KIER  TE      15847 Travis  Kelce  KC    TE    A      10.1    8.7  62.4  97.3  -2.66 
#> 7  2020     3 KIER  FX    4242335 Jonath… Taylor Ind   RB    A      15.3   12.2  82.6  98.6   0.964
#> 8  2020     3 KIER  DS     -16023 Steele… D/ST   Pit   DS    A       7.50   7.5  74.1  93.4  -3.11 
#> 9  2020     3 KIER  PK      14993 Greg    Zuerl… Dal   PK    A       7.91   9    33.8  41.0   2.72
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       4 21.6  
#>  2 Alvin    Kamara      NO    RB    GB       32 14.0  
#>  3 Drew     Brees       NO    QB    GB       30 15.7  
#>  4 Jonathan Taylor      Ind   RB    NYJ      24 16.4  
#>  5 DeAndre  Hopkins     Ari   WR    Det      22 21.9  
#>  6 Odell    Beckham Jr. Cle   WR    Wsh       7 26.3  
#>  7 Travis   Kelce       KC    TE    Bal       7  9.21 
#>  8 David    Johnson     Hou   RB    Pit       2 26.8  
#>  9 Steelers D/ST        Pit   DS    Hou      25  0.594
#> 10 Cooper   Kupp        LAR   WR    Buf      32 16.0  
#> 11 David    Montgomery  Chi   RB    Atl      23 16.5  
#> 12 Ronald   Jones II    TB    RB    Den      31 14.1  
#> 13 Marvin   Jones Jr.   Det   WR    Ari       3 29.1  
#> 14 Mike     Davis       Car   RB    LAC      11 19.2  
#> 15 Deebo    Samuel      SF    WR    NYG      18 22.5

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    18 KIER  QB      14876 Ryan     Tannehill  Ten   QB    ADD    2020-10-21 12:00:34
#>  2  2020    18 KIER  RB    3054850 Alvin    Kamara     NO    RB    DRAFT  2020-09-06 22:17:42
#>  3  2020    18 KIER  RB    4242335 Jonathan Taylor     Ind   RB    DRAFT  2020-09-06 22:17:42
#>  4  2020    18 KIER  WR      15795 DeAndre  Hopkins    Ari   WR    DRAFT  2020-09-06 22:17:42
#>  5  2020    18 KIER  WR    2977187 Cooper   Kupp       LAR   WR    DRAFT  2020-09-06 22:17:42
#>  6  2020    18 KIER  TE      15847 Travis   Kelce      KC    TE    DRAFT  2020-09-06 22:17:42
#>  7  2020    18 KIER  FX    4035538 David    Montgomery Chi   RB    DRAFT  2020-09-06 22:17:42
#>  8  2020    18 KIER  DS     -16002 Bills    D/ST       Buf   DS    ADD    2020-12-24 12:00:08
#>  9  2020    18 KIER  PK      15683 Justin   Tucker     Bal   PK    ADD    2020-12-05 12:00:07
#> 10  2020    18 KIER  BE    2508176 David    Johnson    Hou   RB    DRAFT  2020-09-06 22:17:42
#> 11  2020    18 KIER  BE    3912550 Ronald   Jones II   TB    RB    DRAFT  2020-09-06 22:17:42
#> 12  2020    18 KIER  BE    3025433 Mike     Davis      Car   RB    ADD    2020-09-23 11:00:09
#> 13  2020    18 KIER  BE    3886818 Myles    Gaskin     Mia   RB    ADD    2020-09-30 11:01:14
#> 14  2020    18 KIER  BE    3139522 Travis   Fulgham    Phi   WR    ADD    2020-10-21 12:00:34
#> 15  2020    18 KIER  BE    3128774 Kalen    Ballage    LAC   RB    ADD    2020-11-18 12:00:03
#> 16  2020    18 KIER  BE      11237 Matt     Ryan       Atl   QB    ADD    2020-11-25 12:04:26

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(week = 5)[, 7:14], 
  y = nfl_players[, 1:3]
)
#> # A tibble: 129 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-07 11:44:30     6 BE               NA 3915165 PK           NA LINEUP Rodrigo Blankenship
#>  2 2020-10-07 11:01:36     5 <NA>             NA 3915165 <NA>          5 ADD    Rodrigo Blankenship
#>  3 2020-10-07 11:01:36     6 <NA>             NA 3915165 <NA>          6 ADD    Rodrigo Blankenship
#>  4 2020-10-11 11:00:47    10 <NA>             NA   15091 <NA>         10 ADD    Randy   Bullock    
#>  5 2020-10-07 11:01:36     8 <NA>              8   15091 <NA>         NA DROP   Randy   Bullock    
#>  6 2020-10-11 11:00:47    10 <NA>             10   13981 <NA>         NA DROP   Mark    Ingram II  
#>  7 2020-10-08 11:00:26     8 <NA>             NA 3916430 <NA>          8 ADD    Nyheim  Hines      
#>  8 2020-10-09 13:28:34     8 RB               NA 3916430 BE           NA LINEUP Nyheim  Hines      
#>  9 2020-10-09 13:27:27     8 BE               NA 3916430 RB           NA LINEUP Nyheim  Hines      
#> 10 2020-10-13 11:45:00     8 BE               NA 3916430 RB           NA LINEUP Nyheim  Hines      
#> # … with 119 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    18     1 AGUS        4    54           15    15        59        0      0
#> 2  2020    18     3 PEPE        3    63           17    17        73        2      0
#> 3  2020    18     4 BILL        8   100           19    19        84        4      0
#> 4  2020    18     5 CART        6   100           23    23        61        1      0
#> 5  2020    18     6 KIER        2    98           28    28        64        2      0
#> 6  2020    18     8 CORE        1    52           24    24        72        1      0
#> 7  2020    18    10 NICK        5    94           28    27        63        3      0
#> 8  2020    18    11 KYLE        7   100           21    22        83        1      0

Scores

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

match_scores()
#> # A tibble: 112 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 102 more rows

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

match_schedule()
#> # A tibble: 112 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 102 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    14    53 BILL   162.  162. -92.7
#> 2    14    53 KYLE   255.  255.  92.7
#> 3    14    54 CART   224.  224.  46.7
#> 4    14    54 NICK   177.  177. -46.7
#> 5    14    55 PEPE   200.  200. -65.4
#> 6    14    55 KIER   265.  265.  65.4
#> 7    14    56 AGUS   190.  190.  24.1
#> 8    14    56 CORE   166.  166. -24.1

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: 128 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 118 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    18     1 AGUS       1       5     5     7     2      6     0     6      0.5     1198.
#> 2  2020    18     3 PEPE       7       6     6     6     2      6     0     6      0.5     1151.
#> 3  2020    18     4 BILL       8       1     1     2     0      4     0     8      0.667   1149.
#> 4  2020    18     5 CART       5       3     3     3     2      6     0     6      0.5     1141.
#> 5  2020    18     6 KIER       4       7     7     5     3      7     0     5      0.417   1194.
#> 6  2020    18     8 CORE       6       8     8     8     4      8     0     4      0.333   1319.
#> 7  2020    18    10 NICK       3       4     4     4     2      6     0     6      0.5     1219.
#> 8  2020    18    11 KYLE       2       2     2     1     1      5     0     7      0.583   1274.
#> # … 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