setwd("C:/Users/bbilt/OneDrive/Documents/AthleteLabs")

library(plyr)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:plyr':
## 
##     arrange, count, desc, failwith, id, mutate, rename, summarise,
##     summarize
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(tidyr)
library(devtools)
## Loading required package: usethis
library(data.table)
## 
## Attaching package: 'data.table'
## The following objects are masked from 'package:dplyr':
## 
##     between, first, last
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.5.2
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats   1.0.0     ✔ readr     2.1.5
## ✔ ggplot2   3.5.2     ✔ stringr   1.6.0
## ✔ lubridate 1.9.4     ✔ tibble    3.3.0
## ✔ purrr     1.1.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::arrange()      masks plyr::arrange()
## ✖ data.table::between() masks dplyr::between()
## ✖ purrr::compact()      masks plyr::compact()
## ✖ dplyr::count()        masks plyr::count()
## ✖ dplyr::desc()         masks plyr::desc()
## ✖ dplyr::failwith()     masks plyr::failwith()
## ✖ dplyr::filter()       masks stats::filter()
## ✖ data.table::first()   masks dplyr::first()
## ✖ lubridate::hour()     masks data.table::hour()
## ✖ dplyr::id()           masks plyr::id()
## ✖ lubridate::isoweek()  masks data.table::isoweek()
## ✖ dplyr::lag()          masks stats::lag()
## ✖ data.table::last()    masks dplyr::last()
## ✖ lubridate::mday()     masks data.table::mday()
## ✖ lubridate::minute()   masks data.table::minute()
## ✖ lubridate::month()    masks data.table::month()
## ✖ dplyr::mutate()       masks plyr::mutate()
## ✖ lubridate::quarter()  masks data.table::quarter()
## ✖ dplyr::rename()       masks plyr::rename()
## ✖ lubridate::second()   masks data.table::second()
## ✖ dplyr::summarise()    masks plyr::summarise()
## ✖ dplyr::summarize()    masks plyr::summarize()
## ✖ purrr::transpose()    masks data.table::transpose()
## ✖ lubridate::wday()     masks data.table::wday()
## ✖ lubridate::week()     masks data.table::week()
## ✖ lubridate::yday()     masks data.table::yday()
## ✖ lubridate::year()     masks data.table::year()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(DT)
## Warning: package 'DT' was built under R version 4.5.2
library(ggplot2)
library(ggrepel)
## Warning: package 'ggrepel' was built under R version 4.5.2
library(ggthemes)
## Warning: package 'ggthemes' was built under R version 4.5.2
library(gridExtra)
## Warning: package 'gridExtra' was built under R version 4.5.2
## 
## Attaching package: 'gridExtra'
## 
## The following object is masked from 'package:dplyr':
## 
##     combine
library(janitor)
## Warning: package 'janitor' was built under R version 4.5.2
## 
## Attaching package: 'janitor'
## 
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
library(plotly)
## Warning: package 'plotly' was built under R version 4.5.2
## 
## Attaching package: 'plotly'
## 
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## 
## The following objects are masked from 'package:plyr':
## 
##     arrange, mutate, rename, summarise
## 
## The following object is masked from 'package:stats':
## 
##     filter
## 
## The following object is masked from 'package:graphics':
## 
##     layout
library(stringr)
library(tidyselect)
## Warning: package 'tidyselect' was built under R version 4.5.2
library(data.table)
library(reactable)
## Warning: package 'reactable' was built under R version 4.5.2
ProjectData=fread("Offense Stat Project.csv")

library(dplyr)

 percentiles<- ProjectData %>%
  group_by(Batter) %>%
  summarize(
    
    walks = sum(KorBB == "Walk", na.rm = TRUE),
    strikeouts = sum(KorBB == "Strikeout", na.rm = TRUE),
    singles = sum(PlayResult == "Single", na.rm = TRUE),
    doubles = sum(PlayResult == "Double", na.rm = TRUE),
    triples = sum(PlayResult == "Triple", na.rm = TRUE),
    homers = sum(PlayResult == "HomeRun", na.rm = TRUE),
    sacrifices = sum(PlayResult == "Sacrifice", na.rm = TRUE),
    outs = sum(PlayResult == "Out", na.rm = TRUE),
    errors = sum(PlayResult == "Error", na.rm = TRUE),
    fielders_choice = sum(PlayResult == "FieldersChoice", na.rm = TRUE),
    swings = sum(PitchCall %in% c("FoulBallNotFieldable","InPlay","FoulBallFieldable","StrikeSwinging"), na.rm = TRUE),             
    whiffs = sum(PitchCall == "StrikeSwinging", na.rm = TRUE),  
    whiff_rate = (whiffs / swings) * 100,  
    p90_exit_speed = quantile(ExitSpeed, 0.9, na.rm = TRUE), 
    avg_exit_speed = mean(ExitSpeed, na.rm = TRUE),
    batted_balls = n(),
    plate_appearances = sum(PitchofPA == 1, na.rm = TRUE), 
    strikeout_rate = round((strikeouts / plate_appearances) * 100, 2),
    walk_rate = round((walks / plate_appearances) * 100, 2),
  ) %>%
  mutate(
    
    hits = singles + doubles + triples + homers,
    plate_appearances = hits + walks + strikeouts + sacrifices + outs + errors + fielders_choice,
    at_bats = hits + outs + errors + fielders_choice,  
    total_bases = singles + (2 * doubles) + (3 * triples) + (4 * homers),
    babip = ifelse(
      (at_bats - strikeouts - homers + sacrifices) > 0,
      (hits - homers) / (at_bats - strikeouts - homers + sacrifices),
      NA_real_
    ),
    woba = (
      (0.69 * walks) +
        (0.88 * singles) +
        (1.25 * doubles) +
        (1.58 * triples) +
        (2.03 * homers)
    ) / (at_bats + walks + sacrifices),
    
    woba = ifelse(is.finite(woba), woba, NA_real_),
    avg = hits / at_bats,
    obp = (hits + walks) / (at_bats + walks + sacrifices),
    slg = total_bases / at_bats,
    ops = obp + slg,
    iso = slg - avg,
    rc = ((hits + walks) * total_bases) / (at_bats + walks),
    rc = ifelse(is.finite(rc), rc, NA_real_)
  ) %>%
  filter(at_bats >= 5) %>%  
  ungroup() %>%
  mutate(
    league_ops = mean(ops, na.rm = TRUE),
    ops_plus = round(100 * (ops / league_ops), 0),
    league_iso = mean(iso, na.rm = TRUE),
    iso_plus = round(100 * (iso / league_iso), 0),
    league_babip = mean(babip, na.rm = TRUE),
    babip_plus = round(100 * (babip / league_babip), 0),
    league_woba = mean(woba, na.rm = TRUE),
    woba_plus = round(100 * (woba / league_woba), 0),
    league_mean_whiff = mean(whiff_rate),
    league_sd_whiff = sd(whiff_rate),
    whiff_rate_plus = round(100 + ((league_mean_whiff-whiff_rate) / league_sd_whiff) * 10, 0),
    league_EV90 = mean(p90_exit_speed),
    league_sd_EV90 = sd(p90_exit_speed),
    EV90_plus = round(100 + ((p90_exit_speed - league_EV90) / league_sd_EV90) * 10, 0),
    league_EV = mean(avg_exit_speed),
    league_sd_EV = sd(avg_exit_speed),
    EV_plus = round(100 + ((avg_exit_speed - league_EV) / league_sd_EV) * 10, 0),
    league_K = mean(strikeout_rate),
    league_sd_K = sd(strikeout_rate),
    strikeout_rate_plus = round(100 + ((league_K-strikeout_rate) / league_sd_K) * 10, 0),
    league_BB = mean(walk_rate),
    league_sd_BB = sd(walk_rate),
    walk_rate_plus = round(100 + ((walk_rate - league_BB) / league_sd_BB) * 10, 0),
    league_rc = mean(rc, na.rm = TRUE),
    rc_plus = round(100 * (rc / league_rc), 0)
    
  ) %>%
  select(Batter, iso_plus, ops_plus, babip_plus, woba_plus, rc_plus, whiff_rate_plus, EV90_plus, EV_plus, strikeout_rate_plus, walk_rate_plus) %>%
  arrange(desc(ops_plus))