Skip to content

Commit

Permalink
Merge pull request #274 from dynastyprocess/dev
Browse files Browse the repository at this point in the history
1.4.1 - patch env issue, scoringhistory, starter_positions
  • Loading branch information
tanho63 committed Apr 19, 2021
2 parents 57b7ae2 + 19616b4 commit 0f484da
Show file tree
Hide file tree
Showing 34 changed files with 316 additions and 129 deletions.
3 changes: 2 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Type: Package
Package: ffscrapr
Title: API Client for Fantasy Football League Platforms
Version: 1.4.0
Version: 1.4.1
Authors@R:
c(person(given = "Tan",
family = "Ho",
Expand Down Expand Up @@ -56,6 +56,7 @@ Suggests:
rmarkdown (>= 2.6),
testthat (>= 2.1.0),
withr (>= 2.4.0)
LazyData: true
VignetteBuilder:
knitr
Encoding: UTF-8
Expand Down
22 changes: 20 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,28 @@
# ffscrapr 1.4.1

The main goal of v1.4.1 is to patch some issues raised by CRAN checks and also correct some bugs in the new experimental `ff_scoringhistory` and `ff_starter_positions` functions released in v1.4.0.

## New features

- `nflfastr_stat_mapping` is a dataframe that maps nflfastr columns to fantasy scoring rules, and is now exported for end-user usage. It is primarily used inside of `ff_scoringhistory()`.

## Minor changes

- Added `release_questions` to help remind me to maintain test infrastructure
- `mfl_starter_positions` now correctly calculates offensive starters (first via "iop_starters" if defined and then otherwise by subtracting idp starters) as well as kdst_starters (Resolves #264)
- Redirected nflfastr download functions to the new nflverse/ repository locations. (Resolves #268)
- `.ffscrapr_env` relocated from being a child of the base environment to being a child of the empty environment (Resolves #269)
- `ff_scoringhistory` refactored and adds better support for MFL's fumbles and firstdowns. (Resolves #265)

---

# ffscrapr 1.4.0

The main goal of v1.4.0 is to add preliminary support for connecting ffscrapr to nflfastR weekly data, and to clean up bugs from v1.3.0. Huge thanks goes to [Joe Sydlowski](https://twitter.com/JoeSydlowskiFF) for his contributions on scoring history (and everything else DynastyProcess!)

## New Features
- `nflfastr_weekly()` imports weekly offensive statistics from nflfastR's [data repository](https://github.com/guga31bb/nflfastR-data).
- `nflfastr_rosters()` imports team rosters from nflfastR's [roster repository](https://github.com/mrcaseb/nflfastR-roster).
- `nflfastr_weekly()` imports weekly offensive statistics from nflfastR's [data repository](https://github.com/nflverse/nflfastR-data).
- `nflfastr_rosters()` imports team rosters from nflfastR's [roster repository](https://github.com/nflverse/nflfastR-roster).
- `ff_scoringhistory()` connects your league's scoring settings to the nflfastr data (c/o the functions above), and allows you to reconstruct historical scoring for your league!
- `ff_starter_positions()` describes the starter rules for each player/position, including min and max starters at each position accounting for flex spots. This should be useful for calculating things like value over replacement!

Expand Down
30 changes: 30 additions & 0 deletions R/0_helpers.R
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,33 @@ set_unescaped_cookies <- function(...) {

httr::config(cookie = cookie)
}

#' Release questions
#'
#' @keywords internal
#'
release_bullets <- function(){

#nocov start

c(
"Tag the current version of ffscrapr-tests as a release version",
'Switch all vignettes and tests to use "ffscrapr-tests-v1.x.x" and download "archive/v1.x.x"'
)

#nocov end

}

#' Mappings for nflfastr to fantasy platform scoring
#'
#' A small helper dataframe for connecting nflfastr to specific fantasy platform rules.
#'
#' @format A data frame with ~85 rows and 3 variables:
#' \describe{
#' \item{nflfastr_event}{the column name of the statistic in the nflfastr_weekly dataset}
#' \item{platform}{specific platform that this mapping applies to}
#' \item{ff_event}{name of the statistic for that platform}
#' }
#'
"nflfastr_stat_mapping"
4 changes: 2 additions & 2 deletions R/1_import_nflfastr.R
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
nflfastr_weekly <- function(type = c("offense", "defense", "all")) {
file_name <- match.arg(type)

url_query <- "https://github.com/guga31bb/nflfastR-data/raw/master/data/player_stats.rds"
url_query <- "https://github.com/nflverse/nflfastR-data/raw/master/data/player_stats.rds"

response <- httr::RETRY("GET", url_query)

Expand Down Expand Up @@ -66,7 +66,7 @@ nflfastr_weekly <- function(type = c("offense", "defense", "all")) {
nflfastr_rosters <- function(seasons) {
checkmate::assert_numeric(seasons, lower = 1999, upper = lubridate::year(Sys.Date()))

urls <- glue::glue("https://github.com/mrcaseb/nflfastR-roster/raw/master/data/seasons/roster_{seasons}.rds")
urls <- glue::glue("https://github.com/nflverse/nflfastR-roster/raw/master/data/seasons/roster_{seasons}.rds")

df_rosters <- purrr::map_df(urls, .nflfastr_roster)

Expand Down
8 changes: 5 additions & 3 deletions R/espn_scoringhistory.R
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ ff_scoringhistory.espn_conn <- function(conn, season = 1999:2020, ...) {

# Pull in scoring rules for that league
league_rules <-
ff_scoring(conn)
ff_scoring(conn) %>%
dplyr::left_join(
nflfastr_stat_mapping %>% dplyr::filter(.data$platform == "espn"),
by = c("stat_name" = "ff_event"))

# Use custom ffscrapr function to get positions fron nflfastR rosters
fastr_rosters <-
Expand All @@ -41,8 +44,7 @@ ff_scoringhistory.espn_conn <- function(conn, season = 1999:2020, ...) {
"special_teams_tds"
)
) %>%
dplyr::inner_join(stat_mapping, by = c("metric" = "nflfastr_event")) %>%
dplyr::inner_join(league_rules, by = c("espn_event" = "stat_name", "position" = "pos")) %>%
dplyr::inner_join(league_rules, by = c("metric" = "nflfastr_event", "position" = "pos")) %>%
dplyr::mutate(points = .data$value * .data$points) %>%
dplyr::group_by(.data$season, .data$week, .data$player_id, .data$sportradar_id) %>%
dplyr::mutate(points = round(sum(.data$points, na.rm = TRUE), 2)) %>%
Expand Down
16 changes: 9 additions & 7 deletions R/flea_scoringhistory.R
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@
#'
#' @examples
#' \donttest{
#' #'
#' conn <- fleaflicker_connect(2020, 312861)
#' x <- ff_scoringhistory(conn, season = 2020)
#' x
#' # conn <- fleaflicker_connect(2020, 312861)
#' ff_scoringhistory(conn, season = 2020)
#' }
#'
#' @describeIn ff_scoringhistory Fleaflicker: returns scoring history in a flat table, one row per player per week.
Expand All @@ -22,7 +20,12 @@ ff_scoringhistory.flea_conn <- function(conn, season = 1999:2020, ...) {

# Pull in scoring rules for that league
league_rules <-
ff_scoring(conn)
ff_scoring(conn) %>%
dplyr::left_join(
nflfastr_stat_mapping %>%
dplyr::filter(.data$platform == "fleaflicker") %>%
dplyr::mutate(ff_event = as.integer(.data$ff_event)),
by = c("event_id" = "ff_event"))

# Use custom ffscrapr function to get positions fron nflfastR rosters
fastr_rosters <-
Expand All @@ -43,8 +46,7 @@ ff_scoringhistory.flea_conn <- function(conn, season = 1999:2020, ...) {
"special_teams_tds"
)
) %>%
dplyr::inner_join(stat_mapping, by = c("metric" = "nflfastr_event")) %>%
dplyr::inner_join(league_rules, by = c("fleaflicker_event" = "event_id", "position" = "pos")) %>%
dplyr::inner_join(league_rules, by = c("metric" = "nflfastr_event", "position" = "pos")) %>%
dplyr::mutate(points = .data$value * .data$points) %>%
dplyr::group_by(.data$season, .data$week, .data$player_id, .data$sportradar_id) %>%
dplyr::mutate(points = round(sum(.data$points, na.rm = TRUE), 2)) %>%
Expand Down
30 changes: 23 additions & 7 deletions R/mfl_scoringhistory.R
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,31 @@ ff_scoringhistory.mfl_conn <- function(conn, season = 1999:2020, ...) {
dplyr::mutate(dplyr::across(
.cols = c("lower_range", "upper_range"),
.fns = as.numeric
))
)) %>%
dplyr::left_join(
nflfastr_stat_mapping %>% dplyr::filter(.data$platform == "mfl"),
by = c("event" = "ff_event")) %>%
dplyr::select(
"pos","points","lower_range","upper_range","event", "nflfastr_event", "short_desc"
)

# Use custom ffscrapr function to get positions fron nflfastR rosters
# Use custom ffscrapr function to get positions from nflfastR rosters
fastr_rosters <-
nflfastr_rosters(season) %>%
dplyr::mutate(position = dplyr::if_else(.data$position %in% c("HB", "FB"), "RB", .data$position))

# Load stats from nflfastr and map the rules from the internal stat_mapping file
nflfastr_weekly() %>%
fastr_weekly <- nflfastr_weekly() %>%
dplyr::inner_join(fastr_rosters, by = c("player_id" = "gsis_id", "season" = "season")) %>%
dplyr::select(
"season", "player_id", "sportradar_id", "position", "full_name","recent_team","week",
"completions", "attempts", "passing_yards", "passing_tds", "interceptions", "sacks",
"sack_fumbles_lost", "passing_first_downs", "passing_2pt_conversions", "carries",
"rushing_yards", "rushing_tds", "rushing_fumbles_lost", "rushing_first_downs",
"rushing_2pt_conversions", "receptions", "targets", "receiving_yards", "receiving_tds",
"receiving_fumbles_lost", "receiving_first_downs", "receiving_2pt_conversions",
"special_teams_tds", "sack_yards", "rushing_fumbles", "receiving_fumbles", "sack_fumbles"
) %>%
tidyr::pivot_longer(
names_to = "metric",
cols = c(
Expand All @@ -47,18 +62,17 @@ ff_scoringhistory.mfl_conn <- function(conn, season = 1999:2020, ...) {
"rushing_yards", "rushing_tds", "rushing_fumbles_lost", "rushing_first_downs",
"rushing_2pt_conversions", "receptions", "targets", "receiving_yards", "receiving_tds",
"receiving_fumbles_lost", "receiving_first_downs", "receiving_2pt_conversions",
"special_teams_tds"
"special_teams_tds", "sack_yards", "rushing_fumbles", "receiving_fumbles", "sack_fumbles"
)
) %>%
dplyr::inner_join(stat_mapping, by = c("metric" = "nflfastr_event")) %>%
dplyr::inner_join(league_rules, by = c("mfl_event" = "event", "position" = "pos")) %>%
dplyr::inner_join(league_rules, by = c("metric" = "nflfastr_event", "position" = "pos")) %>%
dplyr::filter(.data$value >= .data$lower_range, .data$value <= .data$upper_range) %>%
dplyr::mutate(points = .data$value * .data$points) %>%
dplyr::group_by(.data$season, .data$week, .data$player_id, .data$sportradar_id) %>%
dplyr::mutate(points = round(sum(.data$points, na.rm = TRUE), 2)) %>%
dplyr::ungroup() %>%
dplyr::select("season", "week",
"gsis_id" = "player_id", "sportradar_id", "player_name", "pos" = "position",
"gsis_id" = "player_id", "sportradar_id", "player_name"="full_name", "pos" = "position",
"team" = "recent_team", "metric", "value", "points"
) %>%
tidyr::pivot_wider(
Expand All @@ -68,4 +82,6 @@ ff_scoringhistory.mfl_conn <- function(conn, season = 1999:2020, ...) {
values_fill = 0,
values_fn = max
)

return(fastr_weekly)
}
16 changes: 13 additions & 3 deletions R/mfl_starterpositions.R
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,43 @@
#'
#' @examples
#' \donttest{
#' dlfidp_conn <- mfl_connect(2020, league_id = 54040)
#' dlfidp_conn <- mfl_connect(2020, league_id = 33158)
#' ff_starter_positions(conn = dlfidp_conn)
#' }
#'
#' @export

ff_starter_positions.mfl_conn <- function(conn, ...) {

starter_positions <- mfl_getendpoint(conn, "league") %>%
purrr::pluck("content", "league", "starters") %>%
list() %>%
tibble::tibble() %>%
tidyr::hoist(1, "total_starters" = "count", "defense_starters" = "idp_starters", "position") %>%
tidyr::hoist(
1,
"total_starters" = "count",
"defense_starters" = "idp_starters",
"offense_starters" = "iop_starters",
"position") %>%
tidyr::unnest_longer("position") %>%
tidyr::hoist("position", "pos" = "name", "limit") %>%
tidyr::separate("limit", into = c("min", "max"), sep = "\\-", fill = "right") %>%
dplyr::mutate_at(c("min", "max", "total_starters"), as.integer) %>%
dplyr::mutate(
max = dplyr::coalesce(.data$max, .data$min),
defense_starters = dplyr::coalesce(as.integer(.data[["defense_starters"]]), 0),
offense_starters = as.integer(.data$total_starters) - .data$defense_starters
kdst_starters = sum(.data$pos %in% c("DEF","PK","PN","TMPK","TMPN","Coach","ST") * .data$min),
offense_starters = dplyr::coalesce(
as.integer(.data[["offense_starters"]]),
as.integer(.data$total_starters) - .data$defense_starters - .data$kdst_starters)
) %>%
dplyr::select(
"pos",
"min",
"max",
"offense_starters",
"defense_starters",
"kdst_starters",
"total_starters"
)

Expand Down
5 changes: 3 additions & 2 deletions R/sleeper_draftpicks.R
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ ff_draftpicks.sleeper_conn <- function(conn, ...) {
purrr::pluck("content")

draft_rounds <- league_settings %>%
purrr::pluck("settings", "draft_rounds") %>%
seq_len()
purrr::pluck("settings", "draft_rounds")

draft_rounds <- seq_len(draft_rounds)

# Seems to be that you can only trade three years in advance, hard-coded into the platform
seasons <- league_settings %>%
Expand Down
12 changes: 7 additions & 5 deletions R/sleeper_scoringhistory.R
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
#' @examples
#' \donttest{
#' #'
#' conn <- ff_connect(platform = "sleeper", league_id = "522458773317046272", season = 2020)
#' ff_scoringhistory(conn, season = 2020)
#' # conn <- ff_connect(platform = "sleeper", league_id = "522458773317046272", season = 2020)
#' # ff_scoringhistory(conn, season = 2020)
#' }
#'
#' @describeIn ff_scoringhistory Sleeper: returns scoring history in a flat table, one row per player per week.
Expand All @@ -21,7 +21,10 @@ ff_scoringhistory.sleeper_conn <- function(conn, season = 1999:2020, ...) {

# Pull in scoring rules for that league
league_rules <-
ff_scoring(conn)
ff_scoring(conn) %>%
dplyr::left_join(
nflfastr_stat_mapping %>% dplyr::filter(.data$platform == "sleeper"),
by = c("event" = "ff_event"))

# Use custom ffscrapr function to get positions fron nflfastR rosters
fastr_rosters <-
Expand All @@ -42,8 +45,7 @@ ff_scoringhistory.sleeper_conn <- function(conn, season = 1999:2020, ...) {
"special_teams_tds"
)
) %>%
dplyr::inner_join(stat_mapping, by = c("metric" = "nflfastr_event")) %>%
dplyr::inner_join(league_rules, by = c("sleeper_event" = "event", "position" = "pos")) %>%
dplyr::inner_join(league_rules, by = c("metric" = "nflfastr_event", "position" = "pos")) %>%
dplyr::mutate(points = .data$value * .data$points) %>%
dplyr::group_by(.data$season, .data$week, .data$player_id, .data$sportradar_id) %>%
dplyr::mutate(points = round(sum(.data$points, na.rm = TRUE), 2)) %>%
Expand Down
Binary file modified R/sysdata.rda
Binary file not shown.
36 changes: 21 additions & 15 deletions R/zzz.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#### On Load ####

.ffscrapr_env <- new.env(parent = emptyenv())

.onLoad <- function(libname, pkgname) {

# nocov start
Expand Down Expand Up @@ -89,21 +91,25 @@

# if (memoise_option == "off") packageStartupMessage('Note: ffscrapr.cache is set to "off"')

env <- rlang::env(
user_agent = glue::glue(
"ffscrapr/{utils::packageVersion('ffscrapr')} API client package",
" https://github.com/dynastyprocess/ffscrapr"
) %>%
httr::user_agent(),
get = ratelimitr::limit_rate(.retry_get, ratelimitr::rate(60, 60)),
get.mfl = ratelimitr::limit_rate(.retry_get, ratelimitr::rate(2, 3)),
get.sleeper = ratelimitr::limit_rate(.retry_get, ratelimitr::rate(30, 2)),
get.flea = ratelimitr::limit_rate(.retry_get, ratelimitr::rate(30, 2)),
get.espn = ratelimitr::limit_rate(.retry_get, ratelimitr::rate(30, 2)),
post = ratelimitr::limit_rate(.retry_post, ratelimitr::rate(60, 60))
)

assign(".ffscrapr_env", env, envir = baseenv())
user_agent <- glue::glue("ffscrapr/{utils::packageVersion('ffscrapr')} ",
"API client package ",
"https://github.com/dynastyprocess/ffscrapr") %>%
httr::user_agent()

# get <- ratelimitr::limit_rate(.retry_get, ratelimitr::rate(60, 60))
get.mfl <- ratelimitr::limit_rate(.retry_get, ratelimitr::rate(2, 3))
get.sleeper <- ratelimitr::limit_rate(.retry_get, ratelimitr::rate(30, 2))
get.flea <- ratelimitr::limit_rate(.retry_get, ratelimitr::rate(30, 2))
get.espn <- ratelimitr::limit_rate(.retry_get, ratelimitr::rate(30, 2))
post <- ratelimitr::limit_rate(.retry_post, ratelimitr::rate(60, 60))


assign("user_agent",user_agent, envir = .ffscrapr_env)
assign("get.mfl",get.mfl, envir = .ffscrapr_env)
assign("get.sleeper",get.sleeper, envir = .ffscrapr_env)
assign("get.flea",get.flea, envir = .ffscrapr_env)
assign("get.espn",get.espn, envir = .ffscrapr_env)
assign("post",post, envir = .ffscrapr_env)

# nocov end
}
Loading

0 comments on commit 0f484da

Please sign in to comment.