---
title: "SwimmeR"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{SwimmeR}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

```{r setup, message = FALSE}
library(SwimmeR)
library(rvest)
library(dplyr)
library(ggplot2)
library(scales)
```

`SwimmeR` was developed to work with results from swimming competitions.  Results are often shared as web pages (.html) or PDF documents, which are nice to read, but make data difficult to access.

`SwimmeR` solves this problem by importing & cleaning .html and .pdf files containing swimming results, and returns a tidy dataframe.

Importing is performed by `read_results` which takes as an argument a file path as `file` and a `node` (for .html only).

In addition to this vignette I do a lot of demos on how to use `SwimmeR` at my blog [Swimming + Data Science](https://pilgrim.netlify.app/).

# Reading PDF Results
*ISL results are handled differently, see ISL section below*
`SwimmeR` includes Texas-Florida-Indiana.pdf, results from a tri-meet between the three schools.  It can be read in as such:

```{r read_results, message = FALSE}
file_path <- system.file("extdata", "Texas-Florida-Indiana.pdf", package = "SwimmeR")

file_read <- read_results(file = file_path)
```

```{r read_results output, message = FALSE}
file_read[294:303]
```

Here we see a subsection of the meet - the top three finishers in the Women's 100 Yard Breaststroke featuring Olympic gold medalist, and the `SwimmeR` package's favorite swimmer, Lilly King.

The next step is to convert this data to a dataframe using `swim_parse`.  Because `swim_parse` works on text strings it is very sensitive to typos and/or nonstandard naming conventions.  "Texas-Florida-Indiana.pdf" has two examples of these potential problems.

The first is that `Indiana University` is sometimes entered as `Indiana  University`, with two spaces between `Indiana` and `University`.  This is a problem because `swim_parse` will interpret two spaces as a column separator, and will not properly capture `Indiana  University` (two spaces) as a team name.

The second issue is that `Texas` and `Florida` are styled as `Texas, University of` and `Florida, University of` which will cause `swim_parse` to interpret them as `Lastname, Firstname`.

Both of these issues can be fixed with the `typo` and `replacement` arguments to `swim_parse`.  Elements of `typo` will be replaced by the element of `replacement` with which they share an index, so all instances of the first element of `typo` will be replaced by the first element of `replacement` etc. etc.  Not specifying `typo` or `replacement` will not produce an error, but might negatively impact the results.  If your results look strange, or are missing values, look for typos related to those swims.

There is a third argument to `swim_parse`, called `avoid`, which will be addressed in the section on reading in html results below.

```{r swim_parse, message = FALSE}
df <-
  swim_parse(
    file = file_read,
    typo = c("Indiana  University", ", University of"),
    replacement = c("Indiana University", "")
  )
```

Here are those same Women's 100 Breaststroke results, as a dataframe in tidy format:
```{r Swim Parse output, message = FALSE}
df[100:102,]
```
*Please note that `SwimmeR` does not capture split times.*

# Reading HTML Results
Reading html results is very similar to reading pdf results, but a value must be specified to `node`, containing which CSS node the `read_results` should look in for results.  Here results from the New York State 2003 Girls Championship meet will be read in, from the "pre" node.

```{r read_results html, message = FALSE}
url <- "http://www.nyhsswim.com/Results/Girls/2003/NYS/Single.htm"
url_read <- read_results(file = url, node = "pre")
```

```{r read_results html output, message = FALSE}
url_read[587:598]
```

Looking at the raw results above one will see that line 2 is a header and contains `NY State Rcd:`, showing the New York State record.  Lines of this type are a common feature in swimming results, but because they contain a recognizable swimming time, without being a result per say, they can cause problems for `swim_parse`.  Like typos these will not cause an error, but might produce nonsense rows in the resulting dataframe.  `swim_parse` deals with strings that should not be included in results with the `avoid` argument.  By default `avoid` contains a lot of common formulations of these header items under `avoid_default`.  You can create your own list of strings as pass it to `avoid`, or add to `avoid_default` via `avoid_new <- c(avoid_default, "your string here")`.  `Avoid` should also include `"r\\:"` if your results have reaction times (`avoid_default` already includes `"r\\:"`). 

```{r swim_parse html, message = FALSE}
df_1 <- swim_parse(file = url_read, avoid = c("NY State Rcd:"))
```

```{r swim_parse html output, message = FALSE}
df_1[358:360,]
```

# Reading ISL Results
International Swimming League results are technically .pdf files, but they're formatted very differently, so they have their own special function, `swim_parse_ISL`.  Handling of ISL results is otherwise the same, with the file first going to `read_results` and then to `swim_parse_ISL`, returning a dataframe.

```{r swim_parse_ISL, message = FALSE}
url <- "https://github.com/gpilgrim2670/Pilgrim_Data/raw/master/ISL/ISL_2019_CollegePark_Day_1.pdf"
url_read <- read_results(url)
df_ISL <- swim_parse_ISL(file = url_read)
```

The `SwimmeR` package's favorite swimmer, Lilly King, is involved in the ISL.  Let's see what she got up to at this particular meet.

```{r swim_parse_ISL output, message = FALSE}
df_ISL[which(df$Name == "KING Lilly"),]
```

Two first place finishes for Ms. King - very nice!  Otherwise all the normal information is here, place, time, team, event etc.  Beginning in the 2020 season ISL starts reporting points in their results, which `swim_parse_ISL` will also read.  At this moment `swim_parse_ISL` does not capture relay swimmers (only the overall relay team), although that function may be added to a future version.

# Formatting Swimming Times

Once results are captured in R as tidy dataframes the real fun can begin - but there's another problem.  Times in swimming are recorded as minutes:seconds.hundredth.  This is fine when a time is less than a minute, because `59.99` can be of class `numeric` in R, but times greater than or equal to a minute `1:00.00` are stuck as class `character`.  `SwimmeR` provides two functions, `sec_format` and `mmss_format` to convert between times as seconds (for doing math), and times as minutes:seconds.hundredths, for swimming-specific display.

```{r formatting times}
data(King200Breast)
King200Breast
```

Included in `SwimmeR` is `King200Breast`, containing all Lilly King's 200 Breaststroke times for her NCAA career.  Times recorded as character values, in standard minutes:seconds.hundredth format.  We can use `sec_format` to format them as seconds, and `mmss_format` to go back to minutes:seconds.hundredth.  Both functions work well with the `tidyverse` packages.

```{r formatting times 2}
King200Breast <- King200Breast %>% 
  dplyr::mutate(Time_sec = sec_format(Time),
         Time_swim_2 = mmss_format(Time_sec))
King200Breast
```

This is useful for comparing times, or plotting
```{r formatted times plot, fig.height = 5, fig.width = 7}
King200Breast %>% 
  ggplot(aes(x = Date, y = Time_sec)) +
  geom_point() +
  scale_y_continuous(labels = scales::trans_format("identity", mmss_format)) +
  theme_classic() +
  labs(y= "Time",
       title = "Lilly King NCAA 200 Breaststroke")
```

# Using `get_mode` to clean swimming data

Swim teams often have abbreviations, for example Lilly King swam for Indiana University, and sometimes "Indiana University" was listed as her team name.  Other times though the team might be listed as "IU" or "IUWSD".  James (Sulley) Sullivan swam (probably) for Monsters University, or MU  Regularizing these names is a useful part of cleaning data.

```{r get_mode setup}
Name <- c(rep("Lilly King", 5), rep("James Sullivan", 3))
Team <- c(rep("IU", 2), "Indiana", "IUWSD", "Indiana University", rep("Monsters University", 2), "MU")
df <- data.frame(Name, Team, stringsAsFactors = FALSE)
df
```

Lilly has 4 different teams, but all of them are actually the same team.  Similarly Sulley has two teams, but actually only one.  Using `get_mode` to return the most frequently occurring team for each swimmer is easier than manually specifying every swimmer's team.

```{r get_mode}
df <- df %>% 
  dplyr::group_by(Name) %>% 
  dplyr::mutate(Team = get_mode(Team))
df
```

# Drawing brackets
To aid in making single elimination brackets for tournaments and shoot-outs `SwimmeR` has `draw_bracket`. Any number of teams between 5 and 64 can be used, with byes automatically assigned to higher seeds.
```{r brackets 1}
teams <- c("red", "orange", "yellow", "green", "blue", "indigo", "violet")
draw_bracket(teams = teams)
```
Now add the results of round two:
```{r brackets 2}
round_two <- c("red", "yellow", "blue", "indigo")
draw_bracket(teams = teams,
             round_two = round_two)
```

And round three:
```{r brackets 3}
round_three <- c("red", "blue")
draw_bracket(teams = teams,
             round_two = round_two,
             round_three = round_three)
```

And crown the champion:
```{r brackets champion}
champion <- "red"
draw_bracket(teams = teams,
             round_two = round_two,
             round_three = round_three,
             champion = champion)
