library(rvest) library(tidyverse) library(nflfastR) library(reactablefmtr)
# Function to pull data from PFR get_pfr_standings <- function(year) { url <- paste0("https://www.pro-football-reference.com/years/",year,"/") AFC_table <- url %>% xml2::read_html() %>% html_nodes(xpath = '//*[@id="AFC"]') %>% html_table() AFC_table <- AFC_table[[1]] NFC_table <- url %>% xml2::read_html() %>% html_nodes(xpath = '//*[@id="NFC"]') %>% html_table() NFC_table <- NFC_table[[1]] NFL_table <- rbind(AFC_table, NFC_table) NFL_table_clean <- NFL_table %>% mutate(Division = ifelse(str_detect(Tm, "FC"), Tm, NA)) %>% fill(Division, .direction = "down") %>% filter(str_detect(Tm, "FC", negate = TRUE)) %>% mutate(Playoffs = ifelse(str_detect(Tm, "[*+]"), "Yes", "No")) %>% mutate(Tm = gsub("[*+]", "", Tm)) %>% rename(Record = `W-L%`) %>% unite(Record, W, L, T, sep = "-") %>% mutate(Team = word(Tm, -1)) %>% mutate( Team = case_when( Team == "Team" ~ "Football Team", TRUE ~ Team ) ) %>% mutate_at(c("SRS", "OSRS", "DSRS", "PF", "PA", "MoV", "SoS"), as.numeric) %>% mutate(SOS = ntile(SoS, 4)) %>% select( Division, Team, Record, Playoffs, SOS, PF, PA, MoV, OSRS, DSRS, SRS, ) } # Join to team logos from {nflfastR} data <- get_pfr_standings(2021) %>% left_join(distinct(select(teams_colors_logos, team_nick, team_logo_espn)), by = c('Team' = 'team_nick')) %>% select(Division, team_logo_espn, everything()) # Create table data %>% mutate( mov_cols = case_when(MoV >= 0 ~ "darkgreen", TRUE ~ "red"), playoff_cols = case_when(Playoffs == "Yes" ~ "darkgreen", TRUE ~ "red") ) %>% reactable( ., theme = fivethirtyeight(centered = TRUE, header_font_size = 11), pagination = FALSE, showSortIcon = FALSE, highlight = TRUE, compact = TRUE, defaultSorted = "SRS", defaultSortOrder = "desc", columnGroups = list( colGroup(name = "Team Rating (SRS)", columns = c("SRS", "OSRS", "DSRS")), colGroup(name = "Team Scoring & Margin of Victory", columns = c("PF", "PA", "MoV")) ), rowStyle = group_border_sort("Division"), columns = list( Division = colDef( name = "Div.", maxWidth = 85, style = group_merge_sort("Division") ), team_logo_espn = colDef( name = "", maxWidth = 75, sortable = FALSE, style = background_img(height = "200%", width = "125%") ), Team = colDef( minWidth = 100, align = "left", cell = merge_column(., "Record", merged_position = "below"), style = list(borderRight = "1px solid #777") ), Record = colDef(show = FALSE), Playoffs = colDef( maxWidth = 70, align = "center", cell = pill_buttons(., color_ref = "playoff_cols", opacity = 0.7), style = list(borderRight = "1px solid #777") ), playoff_cols = colDef(show = FALSE), SOS = colDef( maxWidth = 47, align = "center", cell = icon_sets(., icon_set = "ski rating", icon_position = "over"), style = list(borderRight = "1px solid #777") ), PF = colDef( maxWidth = 180, cell = data_bars(., text_size = 13, box_shadow = TRUE)), PA = colDef( maxWidth = 180, cell = data_bars(., text_size = 13, box_shadow = TRUE)), MoV = colDef( maxWidth = 80, cell = pill_buttons(., number_fmt = function(value) sprintf("%+0.1f", value), colors = "transparent", opacity = 0, bold_text = TRUE, text_color_ref = "mov_cols" ), style = list(borderRight = "1px solid #777") ), mov_cols = colDef(show = FALSE), OSRS = colDef( maxWidth = 55, cell = color_tiles(., bias = 1.3, box_shadow = TRUE) ), DSRS = colDef( maxWidth = 55, cell = color_tiles(., bias = 0.6, box_shadow = TRUE) ), SRS = colDef( maxWidth = 55, cell = color_tiles(., bias = 0.7, box_shadow = TRUE) ) ) ) %>% add_title("2021 NFL Standings & Team Ratings", margin = margin(0, 0, 10, 0)) %>% add_icon_legend(icon_set = "ski rating") %>% add_source("Table created by: Kyle Cuilla @kc_analytics with {reactablefmtr} • Data: Pro-Football-Reference.com", font_size = 12)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.