063: kenpom tier A

gt_tables
Published

December 17, 2023

Load data

Code
cbbdata::cbd_torvik_game_factors(team = "North Carolina") |> 
    dplyr::filter(date %in% c(as.Date("2022-11-25"), as.Date("2022-11-27"), 
                              as.Date("2022-11-30"),
                              as.Date("2022-12-04"), 
                              as.Date("2022-12-17"), 
                              as.Date("2022-12-30"),
                              as.Date("2023-01-10"), 
                              as.Date("2023-02-04"), 
                              as.Date("2023-02-19"), 
                              as.Date("2023-03-04"), 
                              as.Date("2023-03-09"), 
                              as.Date("2023-11-23"), 
                              as.Date("2023-11-29"), 
                              as.Date("2023-12-05"), 
                              as.Date("2023-12-16")
    )) |> 
    dplyr::mutate(season = dplyr::if_else(is.na(season), 2024, season),
                  diff = pts_scored - pts_allowed,
                  loc = dplyr::if_else(
                      opp %in% c("Kentucky", "Connecticut", "Villanova"), "N",
                      loc,
                  ), 
                  loc = dplyr::if_else(
                      opp %in% c("Tennessee"), "H",
                      loc,
                  ),
                 outcome = paste0(result, ", ", pts_scored, "-", pts_allowed),
                 opp = dplyr::if_else(opp == "North Carolina St.", "NC State", opp), 
                 outcome = dplyr::if_else(opp == "Alabama", "L, 101-103 4OT", outcome), 
                 outcome = dplyr::if_else(opp == "Villanova", "L, 81-83 OT", outcome), 
                 outcome = dplyr::if_else(opp == "Ohio St.", "W, 89-84 OT", outcome),
                 logo = opp) |> 
    dplyr::select(season, logo, opp, loc, outcome, diff) |> 
    dplyr::arrange(-season) -> kp_opp

GT Tables

Code
gt_theme_athletic <- function(gt_object, ...) {
  
  # get id, if one is passed through to use with CSS
  table_id <- subset(gt_object[['_options']], parameter == 'table_id')$value[[1]]
  
  table <- gt_object |> 
    # set table font
    gt::opt_table_font(
      font = list(
        gt::google_font('Spline Sans Mono'),
        gt::default_fonts()
      ),
      weight = 500
    ) |> 
    # set the column label font and style
    gt::tab_style(
      locations = gt::cells_column_labels(
        columns = gt::everything()
      ),
      style = gt::cell_text(
        font = gt::google_font('Work Sans'),
        weight = 650,
        size = gt::px(14),
        transform = 'uppercase', # column labels to uppercase
        align = 'left'
      )
    ) |> 
    gt::tab_style(
      locations = gt::cells_title('title'),
      style = gt::cell_text(
        font = gt::google_font('Work Sans'),
        weight = 650
      )
    ) |> 
    gt::tab_style(
      locations = gt::cells_title('subtitle'),
      style = gt::cell_text(
        font = gt::google_font('Work Sans'),
        weight = 500
      )
    ) |>
    # set think black column sep.
    gt::tab_style(
      style = gt::cell_borders(sides = 'left', weight = gt::px(0.5), color = 'black'),
      locations = gt::cells_body(
        # everything but the first column
        columns = c(-names(gt_object[['_data']])[1])
      )
    ) |> 
    # set thin dotted row sep.
    gt::tab_style(
      style = gt::cell_borders(sides = "top", color = 'black', weight = gt::px(1.5), style = 'dotted'),
      locations = gt::cells_body(
        rows = gt::everything()
      )
    )|>
    # left align cell text
    gt::cols_align(
      align = 'left',
      columns = gt::everything()
    ) |> 
    gt::tab_options(
      table.font.size = 14,
      column_labels.border.bottom.width = 2,
      column_labels.border.bottom.color = 'black',
      column_labels.border.top.color = 'white',
      row_group.border.bottom.color = 'white',
      table.border.top.style = 'none',
      table.border.bottom.style = 'none',
      heading.border.bottom.style = 'none',
      heading.align = 'left',
      heading.title.font.size = gt::px(30),
      source_notes.border.lr.style = 'none',
      source_notes.font.size = 10
    )
  
  # add css if table id is passed through
  table <- if(!is.null(table_id)) {
    table |> 
      # remove the border from the bottom cell
      gt::opt_css(
        paste0("#", table_id, " tbody tr:last-child {border-bottom: 2px solid #ffffff00;}"),
        add = TRUE
      )
  }
  
  return(table)
  
}

# helper function to stack tables
stack_gt_tables <- function (tables = NULL, output = "viewer", filename = NULL,
                             path = NULL, vwidth = 992, vheight = 1200, ..., zoom = 2,
                             expand = 5)
{
  # divs for each table // change style from gt_two_column_layout
  stacked_tables <- htmltools::div(
    htmltools::div(tables[[1]], style = "display: block; width: 100%;"),
    htmltools::div(tables[[2]], style = "display: block; width: 100%;")
  )

  # carry rest of gt_two_column_layout
  if (output == "viewer") {
    htmltools::browsable(stacked_tables)
  }
  else if (output == "save") {

    filename <- if (is.null(filename)) tempfile(fileext = ".png") else filename
    filename <- if (is.null(path)) filename else file.path(path, filename)

    tempfile_ <- tempfile(fileext = ".html")
    htmltools::save_html(html = stacked_tables, file = tempfile_)

    webshot2::webshot(url = paste0("file:///", tempfile_),
                      file = filename, vwidth = vwidth, vheight = vheight,
                      zoom = zoom, expand = expand, ...)

  }
  else if (output == "html") {
    stacked_tables
  }
}

kp_opp |> 
    gt::gt() |> 
    cfbplotR::gt_fmt_cfb_logo(columns = c(logo)) |> 
    gt::fmt(
        columns = c(diff),
        fns = function(x) {
            ifelse(x > 0, paste0("+", x), x)
        }
    ) |> 
    gtExtras::gt_highlight_rows(
        rows = c(3, 11),
        fill = "#d0e4f3",
        bold_target_only = TRUE,
        target_col = c(outcome),
    ) |> 
    gt::cols_label(logo = "",
                   opp = "Opponent", 
                   outcome = "Result", 
                   loc = "Location",
                   diff = "+/-") |> 
    gt_theme_athletic() |>  
    gt::tab_header(title = "North Carolina is 2-13 against kenpom Tier A opponents  \nsince the start of last season", 
                   subtitle = "The 13 losses are by a combined 81 points or average margin defeat of 6.2 points") |> 
    gt::tab_source_note(source_note = "Bless your chart | data via cbbdata | December 18, 2023") -> kp_tbl 
    
    
gtExtras::gtsave_extra(kp_tbl, filename = "kp_table.png", vheight = 975, vwidth = 775)

kp_tbl
North Carolina is 2-13 against kenpom Tier A opponents since the start of last season
The 13 losses are by a combined 81 points or average margin defeat of 6.2 points
season Opponent Location Result +/-
2024 Kentucky N L, 83-87 -4
2024 Connecticut N L, 76-87 -11
2024 Tennessee H W, 100-92 +8
2024 Villanova N L, 81-83 OT -2
2023 Virginia N L, 59-68 -9
2023 Duke H L, 57-62 -5
2023 NC State A L, 69-77 -8
2023 Duke A L, 57-63 -6
2023 Virginia A L, 58-65 -7
2023 Pittsburgh A L, 74-76 -2
2023 Ohio St. N W, 89-84 OT +5
2023 Virginia Tech A L, 72-80 -8
2023 Indiana A L, 65-77 -12
2023 Alabama N L, 101-103 4OT -2
2023 Iowa St. N L, 65-70 -5
Bless your chart | data via cbbdata | December 18, 2023