---
title: "Visualize Baseball with sunburstR"
author: "Kenton Russell"
date: "August 26, 2016"
output:
  html_document:
    mathjax: null
    theme: null
    css: https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, warning=FALSE, message=FALSE)
```
<!-- Tim Holman awesome github corners -->
<a href="https://github.com/timelyportfolio/sunburstR" class="github-corner" aria-label="View source on Github"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a>
<style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>


<div class="container" style="max-width:900px;">

Sunburst charts from [`sunburstR`](https://github.com/timelyportfolio/sunburstR) work well in sports.  Let's look at a couple of simple examples of interactive sunburst visualizations with baseball data.  We'll be using [`pitchRx`](https://github.com/cpsievert/pitchRx) from [Carson Sievert \@cpsievert](https://twitter.com/cpsievert) to scrape baseball game data.  To replicate these examples, please install any missing packages you see in the following code.

```{r eval=FALSE}
devtools::install_github("cpsievert/XML2R")
devtools::install_github("cpsievert/pitchRx")
devtools::install_github("timelyportfolio/sunburstR")
install.packages("dplyr")
install.packages("tidyr")
install.packages("stringr")
install.packages("rvest")
````

## Sequence of Action

`pitchRx` provides lots of sunburst-able sequence.  I think the easiest sequence will be the data in `runner`.  This allows us to see all the action that moves a runner to base or on base.  Although this data is "easy", you might wonder later why we don't add to 3 outs, so remember this is a partial look at all action.

### Scrape with pitchRx

```{r}
library(sunburstR)
library(pitchRx)
library(dplyr)

# get all data from 2016-08-25
dat <- scrape(start = "2016-08-25", end = "2016-08-25")
```

### Make the Data sunburst-able 

```{r}
# use runner data to get idea of action with a runner on base
#  please note this will not be all action from a game
#  but I think it is an easier dataset to understand
action <- dat$runner %>%
  group_by(event_num) %>%
  filter(row_number() == 1) %>%
  ungroup() %>%
  group_by(gameday_link, inning, inning_side) %>%
  summarize(event = paste(c(event),collapse="-"))

sequences <- action %>%
  ungroup() %>%
  group_by(event) %>%
  summarize(count = n())

# sorry this is messy, but get data in a form
#  so sunburst can build hierarchy
#  which means we will sort in descending order of depth
# note: this will eventually improve
sequences$depth <- unlist(lapply(strsplit(sequences$event,"-"),length))
```

### Create a Sunburst

```{r}
sb <- sequences %>%
  arrange(desc(depth), event) %>%
  sunburst()
sb
```

### Use Sunburst Events

In this [commit](https://github.com/timelyportfolio/sunburstR/commit/7f6879f779d0062699f758795231ecdcd9465777), we added some basic event dispatch to `sunburstR` that can be used in Shiny and non-Shiny contexts.  We will use it to display a link to the games that fit the hovered paths.

```{r}
# use sunburst event handling to provide games for hovered sequence
library(htmltools)

sb$x$tasks <- list(htmlwidgets::JS(
'
function(){
  var chart = this.instance.chart;
  chart.on("mouseover",mouseovered);
}
'
))

sb$height = 400
sb$width = 600

tagList(
  sb,
  tags$div(id="games", style="margin-top:100px"),
  tags$script(HTML(
    sprintf(
'
var action = %s;

function mouseovered(d){
var thiz = this;
var games = action.filter(function(evt){
  return evt.event === thiz.join("-");
});

var div = document.getElementById("games");
div.innerHTML = games.map(function(game){
  return [
    "<a href=\'http://gd2.mlb.com/components/game/mlb/year_2016/month_08/day_25/",
    game.gameday_link,
    "\'>",
    game.gameday_link,
    "</a><br/>"
  ].join("");
}).join("\\n");
}
',
      jsonlite::toJSON(action, auto_unbox=TRUE, dataframe="row")
    )
  ))
)
```


## Sequence of Pitches

[Dan Malter](http://danmalter.github.io/) wrote a fantastic post [Using Markov Chains to Predict Pitches](http://danmalter.github.io/r/2016/03/28/Markov-chains.html).  Let's visualize his pitch data for Jake Arrieta.

### Scrape the Data

```{r}
# pitch sequence data from Markov Chain
#   http://danmalter.github.io/r/2016/03/28/Markov-chains.html
library(sunburstR)
library(rvest)
library(stringr)
library(tidyr)
library(dplyr)

# get table from post to avoid having to run all the code
ht <- read_html("http://danmalter.github.io/r/2016/03/28/Markov-chains.html")
# get pitch type as proportion of total pitches
ht_pitch_arrieta <- html_table(
  xml_find_first(ht,'//*[@id="jake-arrieta---overall-pitch-proportions"]/table')
)
# get markov table for pitch and following pitch
ht_tbl_arrieta <- html_text(
  xml_find_all(ht,'//*[@id="jake-arrieta---multi-class-markov-chain"]/pre/code')[2]
)
ht_tbl_arrieta <- str_replace_all(
  ht_tbl_arrieta,
  c("4-seam FB"="4seamFB", "Int. Ball"="IntBall")
)
tbl <- read.table(
  textConnection(ht_tbl_arrieta),
  skip=2,
  header=FALSE,
  stringsAsFactors=FALSE
)
colnames(tbl) <- c("pitch",tbl[,1])

# multiple by pct of total
tbl[,-1] <- tbl[,-1] * t(ht_pitch_arrieta)

tbl_long <- gather(tbl, key=pitch2, value=value, -pitch)
```


### Draw the Sunburst

```{r}
tbl_long %>%
  mutate(path = paste(pitch,pitch2,sep="-")) %>%
  select(path, value) %>%
  sunburst()
```

## Thanks

Thanks so much to [Kerry Rodden](https://twitter.com/kerryrodden) who provided the original [sunburst](http://bl.ocks.org/kerryrodden/7090426) on which this is based.

Thanks [Mike Bostock](https://bost.ocks.org/mike/) for [d3.js](https://d3js.org) (*please give us a way to pay you*).

Thanks [Tim Holman](http://tholman.com/) for the great [github-corners](http://tholman.com/github-corners/).

Thanks [skeleton](http://getskeleton.com/).

Thanks Carson Sievert for `pitchRx` and all your work on [`plotly`](https://github.com/ropensci/plotly).

Thanks Dan Malter for the great markov pitch post.

</div>
