The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.

Fleaflicker: Basics

Tan Ho

2023-02-11

In this vignette, I’ll walk through how to get started with a basic dynasty value analysis on Fleaflicker.

We’ll start by loading the packages:

  library(ffscrapr)
  library(dplyr)
  library(tidyr)

In Fleaflicker, you can find the league ID by looking in the URL - it’s the number immediately after /league/ in this example URL: https://www.fleaflicker.com/nfl/leagues/312861.

Let’s set up a connection to this league:

aaa <- fleaflicker_connect(season = 2020, league_id = 312861)

aaa
#> <Fleaflicker connection 2020_312861>
#> List of 4
#>  $ platform  : chr "Fleaflicker"
#>  $ season    : chr "2020"
#>  $ user_email: NULL
#>  $ league_id : chr "312861"
#>  - attr(*, "class")= chr "flea_conn"

I’ve done this with the fleaflicker_connect() function, although you can also do this from the ff_connect() call - they are equivalent. Most if not all of the remaining functions after this point are prefixed with “ff_”.

Cool! Let’s have a quick look at what this league is like.


aaa_summary <- ff_league(aaa)

str(aaa_summary)
#> tibble [1 × 15] (S3: tbl_df/tbl/data.frame)
#>  $ league_id      : chr "312861"
#>  $ league_name    : chr "Avid Auctioneers Alliance"
#>  $ season         : int 2020
#>  $ league_type    : chr "dynasty"
#>  $ franchise_count: num 12
#>  $ qb_type        : chr "2QB/SF"
#>  $ idp            : logi FALSE
#>  $ scoring_flags  : chr "0.5_ppr, PP1D"
#>  $ best_ball      : logi FALSE
#>  $ salary_cap     : logi FALSE
#>  $ player_copies  : num 1
#>  $ qb_count       : chr "1-2"
#>  $ roster_size    : int 28
#>  $ league_depth   : num 336
#>  $ keeper_count   : int 31

Okay, so it’s the Avid Auctioneers Alliance, it’s a 2QB league with 12 teams, half ppr scoring, and rosters about 340 players.

Let’s grab the rosters now.

aaa_rosters <- ff_rosters(aaa)

head(aaa_rosters)
#> # A tibble: 6 × 7
#>   franchise_id franchise_name player_id player_name   pos   team  sportradar_id 
#>          <int> <chr>              <int> <chr>         <chr> <chr> <chr>         
#> 1      1578553 Running Bear       12032 Carson Wentz  QB    IND   e9a5c16b-4472…
#> 2      1578553 Running Bear       12159 Dak Prescott  QB    DAL   86197778-8d4b…
#> 3      1578553 Running Bear       13325 Austin Ekeler RB    LAC   e5b8c439-a48a…
#> 4      1578553 Running Bear       12926 Chris Godwin  WR    TB    baa61bb5-f8d0…
#> 5      1578553 Running Bear       16250 Ja'Marr Chase WR    CIN   fa99e984-d63b…
#> 6      1578553 Running Bear        6660 Antonio Brown WR    TB    16e33176-b73e…

Values

Cool! Let’s pull in some additional context by adding DynastyProcess player values.

player_values <- dp_values("values-players.csv")

# The values are stored by fantasypros ID since that's where the data comes from. 
# To join it to our rosters, we'll need playerID mappings.

player_ids <- dp_playerids() %>% 
  select(sportradar_id,fantasypros_id) %>% 
  filter(!is.na(sportradar_id),!is.na(fantasypros_id))

# We'll be joining it onto rosters, so we can trim down the values dataframe
# to just IDs, age, and values

player_values <- player_values %>% 
  left_join(player_ids, by = c("fp_id" = "fantasypros_id")) %>% 
  select(sportradar_id,age,ecr_2qb,ecr_pos,value_2qb)

# ff_rosters() will return the sportradar_id, which we can then match to our player values!

aaa_values <- aaa_rosters %>% 
  left_join(player_values, by = c("sportradar_id"="sportradar_id")) %>% 
  arrange(franchise_id,desc(value_2qb))

head(aaa_values)
#> # A tibble: 6 × 11
#>   franchise_id franc…¹ playe…² playe…³ pos   team  sport…⁴   age ecr_2qb ecr_pos
#>          <int> <chr>     <int> <chr>   <chr> <chr> <chr>   <dbl>   <dbl>   <dbl>
#> 1      1578553 Runnin…   12159 Dak Pr… QB    DAL   861977…  27.9    10.3     4.4
#> 2      1578553 Runnin…   16250 Ja'Mar… WR    CIN   fa99e9…  21.3    41.9    13.8
#> 3      1578553 Runnin…   12926 Chris … WR    TB    baa61b…  25.3    42.6    13.8
#> 4      1578553 Runnin…   16259 Trey L… QB    SF    676a50…  21.1    43.3    13  
#> 5      1578553 Runnin…   13325 Austin… RB    LAC   e5b8c4…  26.1    48.4    16.2
#> 6      1578553 Runnin…   15531 Brando… WR    SF    c90471…  23.2    57.1    20.4
#> # … with 1 more variable: value_2qb <int>, and abbreviated variable names
#> #   ¹​franchise_name, ²​player_id, ³​player_name, ⁴​sportradar_id
#> # ℹ Use `colnames()` to see all variable names

Let’s do some team summaries now!

value_summary <- aaa_values %>% 
  group_by(franchise_id,franchise_name,pos) %>% 
  summarise(total_value = sum(value_2qb,na.rm = TRUE)) %>%
  ungroup() %>% 
  group_by(franchise_id,franchise_name) %>% 
  mutate(team_value = sum(total_value)) %>% 
  ungroup() %>% 
  pivot_wider(names_from = pos, values_from = total_value) %>% 
  arrange(desc(team_value)) %>% 
  select(franchise_id,franchise_name,team_value,QB,RB,WR,TE)

value_summary
#> # A tibble: 12 × 7
#>    franchise_id franchise_name        team_value    QB    RB    WR    TE
#>           <int> <chr>                      <int> <int> <int> <int> <int>
#>  1      1581722 syd12nyjets's Team         42601 12120 10478 19263   740
#>  2      1581719 Jmuthers's Team            42502 12069 19213  3641  7579
#>  3      1581803 ZachFarni's Team           39715  5908 20641 12931   235
#>  4      1582416 Ray Jay Team               37522  3843  7855 15337 10487
#>  5      1582423 The Verblanders            31289 10117  9972 10878   322
#>  6      1581721 Mjenkyns2004's Team        30245 13421  4682 11325   817
#>  7      1581718 Officially Rebuilding      29336  6340  7124 12921  2951
#>  8      1578553 Running Bear               29082 14002  3464 11551    65
#>  9      1581988 The DK Crew                28349 11822  8480  6218  1773
#> 10      1581726 SCJaguars's Team           26596  6999 10538  8510   549
#> 11      1581753 fede_mndz's Team           26485  2489 10871 12673   452
#> 12      1581720 brosene's Team             16432    NA  8277  6190  1965

So with that, we’ve got a team summary of values! I like applying some context, so let’s turn these into percentages - this helps normalise it to your league environment.

value_summary_pct <- value_summary %>% 
  mutate_at(c("team_value","QB","RB","WR","TE"),~.x/sum(.x)) %>% 
  mutate_at(c("team_value","QB","RB","WR","TE"),round, 3)

value_summary_pct
#> # A tibble: 12 × 7
#>    franchise_id franchise_name        team_value    QB    RB    WR    TE
#>           <int> <chr>                      <dbl> <dbl> <dbl> <dbl> <dbl>
#>  1      1581722 syd12nyjets's Team         0.112    NA 0.086 0.147 0.026
#>  2      1581719 Jmuthers's Team            0.112    NA 0.158 0.028 0.271
#>  3      1581803 ZachFarni's Team           0.104    NA 0.17  0.098 0.008
#>  4      1582416 Ray Jay Team               0.099    NA 0.065 0.117 0.375
#>  5      1582423 The Verblanders            0.082    NA 0.082 0.083 0.012
#>  6      1581721 Mjenkyns2004's Team        0.08     NA 0.039 0.086 0.029
#>  7      1581718 Officially Rebuilding      0.077    NA 0.059 0.098 0.106
#>  8      1578553 Running Bear               0.077    NA 0.028 0.088 0.002
#>  9      1581988 The DK Crew                0.075    NA 0.07  0.047 0.063
#> 10      1581726 SCJaguars's Team           0.07     NA 0.087 0.065 0.02 
#> 11      1581753 fede_mndz's Team           0.07     NA 0.089 0.096 0.016
#> 12      1581720 brosene's Team             0.043    NA 0.068 0.047 0.07

Armed with a value summary like this, we can see team strengths and weaknesses pretty quickly, and figure out who might be interested in your positional surpluses and who might have a surplus at a position you want to look at.

Age

Another question you might ask: what is the average age of any given team?

I like looking at average age by position, but weighted by dynasty value. This helps give a better idea of age for each team - including who might be looking to offload an older veteran!

age_summary <- aaa_values %>% 
  filter(pos %in% c("QB","RB","WR","TE")) %>% 
  group_by(franchise_id,pos) %>% 
  mutate(position_value = sum(value_2qb,na.rm=TRUE)) %>% 
  ungroup() %>% 
  mutate(weighted_age = age*value_2qb/position_value,
         weighted_age = round(weighted_age, 1)) %>% 
  group_by(franchise_id,franchise_name,pos) %>% 
  summarise(count = n(),
            age = sum(weighted_age,na.rm = TRUE)) %>% 
  pivot_wider(names_from = pos,
              values_from = c(age,count))

age_summary
#> # A tibble: 12 × 10
#> # Groups:   franchise_id, franchise_name [12]
#>    franchi…¹ franc…² age_QB age_RB age_TE age_WR count…³ count…⁴ count…⁵ count…⁶
#>        <int> <chr>    <dbl>  <dbl>  <dbl>  <dbl>   <int>   <int>   <int>   <int>
#>  1   1578553 Runnin…   26     26      8.4   23.5       6       5       3      14
#>  2   1581718 Offici…   31.4   24.5   21.1   26.4       3       8       2       8
#>  3   1581719 Jmuthe…   24.7   24.8   26.7   28.4       4       5       4       9
#>  4   1581720 brosen…   NA     25.7   24.6   26.3      NA       7       2       5
#>  5   1581721 Mjenky…   25.7   23     23.4   26.6       4       6       5       8
#>  6   1581722 syd12n…   24.4   23     25.5   22.5       5       5       4      14
#>  7   1581726 SCJagu…   22.2   24.3   26.3   24         5       7       4      10
#>  8   1581753 fede_m…   30.3   24.9   23.5   27.7       5       9       3      10
#>  9   1581803 ZachFa…   28.3   22.3   26.7   24.3       4       6       5      12
#> 10   1581988 The DK…   25.8   22.5   24.2   27.7       5       6       5       8
#> 11   1582416 Ray Ja…   30.8   27.2   29.9   25.7       3       3       7       7
#> 12   1582423 The Ve…   24.4   25.7   26.7   27.3       3       5       2       9
#> # … with abbreviated variable names ¹​franchise_id, ²​franchise_name, ³​count_QB,
#> #   ⁴​count_RB, ⁵​count_TE, ⁶​count_WR

Next steps

In this vignette, I’ve used only a few functions: ff_connect, ff_league, ff_rosters, and dp_values. Now that you’ve gotten this far, why not check out some of the other possibilities?

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.