<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Rubix³: A Data Blog</title>
    <link>/</link>
    <description>Recent content on Rubix³: A Data Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Sun, 18 Nov 2018 00:00:00 +0000</lastBuildDate>
    
        <atom:link href="/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>NCAA Basketball: Clustering Conferences</title>
      <link>/ncaa-conferences/</link>
      <pubDate>Sun, 18 Nov 2018 00:00:00 +0000</pubDate>
      
      <guid>/ncaa-conferences/</guid>
      <description>
&lt;script src=&#34;/rmarkdown-libs/kePrint/kePrint.js&#34;&gt;&lt;/script&gt;


&lt;p&gt;With the recent start of the college basketball season, I thought it would be fun to explore how style of play varies between conferences and reveal how the game has changed over time. Using yearly data for each school found on &lt;a href=&#34;https://kenpom.com/&#34;&gt;kenpom.com&lt;/a&gt;, a site for advanced college basketball stats, I examined the state of college hoops.&lt;/p&gt;
&lt;hr /&gt;
&lt;div id=&#34;data-pre-processing&#34; class=&#34;section level1&#34;&gt;
&lt;h1&gt;Data Pre-Processing&lt;/h1&gt;
&lt;div id=&#34;load-packages&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Load Packages&lt;/h2&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;library(tidyverse)
library(rvest)
library(stringi)
library(kableExtra)
library(ggthemr)
library(factoextra)
library(cluster)
library(NbClust)
library(plotly)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div id=&#34;scrape-and-clean-data&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Scrape and Clean Data&lt;/h2&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;#define column names
variables &amp;lt;- c(&amp;quot;Team&amp;quot;, &amp;quot;Conference&amp;quot;, &amp;quot;Record&amp;quot;, &amp;quot;AdjEM&amp;quot;, &amp;quot;AdjO&amp;quot;, &amp;quot;AdjD&amp;quot;, &amp;quot;AdjT&amp;quot;, &amp;quot;Luck&amp;quot;, &amp;quot;SOS.AdjEM&amp;quot;, &amp;quot;OppO&amp;quot;, &amp;quot;OppD&amp;quot;, &amp;quot;NC.SOS.AdjEM&amp;quot;)

#scrape kenpom data
seasons &amp;lt;- lapply(paste0(&amp;#39;https://kenpom.com/index.php?y=&amp;#39;, 2002:2018),
                function(url){
                    url %&amp;gt;% 
                    read_html() %&amp;gt;% 
                    html_nodes(&amp;quot;table&amp;quot;) %&amp;gt;%
                    html_table() %&amp;gt;%
                    as.data.frame() %&amp;gt;%
                    select(-c(Var.1, Var.7, Var.9, Var.11, Var.13,
                                  Strength.of.Schedule.1, 
                                  Strength.of.Schedule.3, 
                                  Strength.of.Schedule.5, NCSOS.1)) %&amp;gt;%
                    `colnames&amp;lt;-`(variables) %&amp;gt;%
                    filter(!is.na(as.numeric(OppO))) %&amp;gt;%
                    mutate(year = stri_sub(url, from = -4, length = 4))
                })

#combine yearly data
ncaa &amp;lt;- do.call(rbind, seasons) %&amp;gt;% 
  separate(Record, into = c(&amp;quot;Wins&amp;quot;, &amp;quot;Losses&amp;quot;)) #extract wins/losses 

ncaa[,3:13] &amp;lt;- lapply(ncaa[,3:13], as.numeric) #convert to numeric values
ncaa$Team &amp;lt;- gsub(&amp;#39;[0-9]+&amp;#39;, &amp;quot;&amp;quot;, ncaa$Team) %&amp;gt;% #remove ncaa/nit tourney rank
  trimws(&amp;quot;r&amp;quot;) #remove trailing spaces
ncaa$Conference &amp;lt;- recode(ncaa$Conference, P10 = &amp;quot;P12&amp;quot;) #combine pac10 with pac12&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In total, we’ll examine 17 years of data including 5,804 individual team seasons. Each season will be classified according to the year it ends, not the year it starts. For example, the 2017-18 college basketball season will be labeled simply as “2018”. A quick look at how the data is organized is shown below.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;glimpse(ncaa)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## Observations: 5,804
## Variables: 14
## $ Team         &amp;lt;chr&amp;gt; &amp;quot;Duke&amp;quot;, &amp;quot;Cincinnati&amp;quot;, &amp;quot;Maryland&amp;quot;, &amp;quot;Kansas&amp;quot;, &amp;quot;Oklaho…
## $ Conference   &amp;lt;chr&amp;gt; &amp;quot;ACC&amp;quot;, &amp;quot;CUSA&amp;quot;, &amp;quot;ACC&amp;quot;, &amp;quot;B12&amp;quot;, &amp;quot;B12&amp;quot;, &amp;quot;B10&amp;quot;, &amp;quot;SEC&amp;quot;, &amp;quot;…
## $ Wins         &amp;lt;dbl&amp;gt; 31, 31, 32, 33, 31, 25, 22, 26, 26, 22, 26, 22, 24,…
## $ Losses       &amp;lt;dbl&amp;gt; 4, 4, 4, 4, 5, 12, 9, 9, 9, 10, 7, 10, 10, 6, 10, 6…
## $ AdjEM        &amp;lt;dbl&amp;gt; 34.19, 30.19, 29.25, 28.99, 26.04, 24.80, 24.72, 23…
## $ AdjO         &amp;lt;dbl&amp;gt; 121.0, 118.1, 119.2, 118.7, 114.9, 114.0, 115.1, 11…
## $ AdjD         &amp;lt;dbl&amp;gt; 86.8, 87.9, 89.9, 89.7, 88.9, 89.2, 90.4, 92.5, 96.…
## $ AdjT         &amp;lt;dbl&amp;gt; 74.5, 67.4, 73.7, 77.3, 66.5, 65.6, 69.6, 68.5, 71.…
## $ Luck         &amp;lt;dbl&amp;gt; -0.027, 0.002, 0.025, 0.022, 0.043, -0.049, -0.073,…
## $ SOS.AdjEM    &amp;lt;dbl&amp;gt; 9.87, 6.58, 9.88, 10.66, 8.77, 14.11, 9.11, 10.60, …
## $ OppO         &amp;lt;dbl&amp;gt; 109.1, 106.3, 109.1, 110.3, 109.0, 110.8, 108.1, 10…
## $ OppD         &amp;lt;dbl&amp;gt; 99.2, 99.7, 99.3, 99.6, 100.2, 96.7, 99.0, 99.1, 99…
## $ NC.SOS.AdjEM &amp;lt;dbl&amp;gt; 6.66, 3.48, 1.62, 8.32, -0.45, 13.53, -0.56, 6.78, …
## $ year         &amp;lt;chr&amp;gt; &amp;quot;2002&amp;quot;, &amp;quot;2002&amp;quot;, &amp;quot;2002&amp;quot;, &amp;quot;2002&amp;quot;, &amp;quot;2002&amp;quot;, &amp;quot;2002&amp;quot;, &amp;quot;20…&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;pace-of-play&#34; class=&#34;section level1&#34;&gt;
&lt;h1&gt;Pace of Play&lt;/h1&gt;
&lt;div id=&#34;overall-tempo&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Overall Tempo&lt;/h2&gt;
&lt;p&gt;To begin, let’s look at how tempo has varied over time. Kenpom defines tempo as a team’s total possessions per 40 minutes (the length of a game minus overtime) adjusted for opponent. So, in general, the greater the tempo, the faster pace a team plays at. The plot below maps how tempo has evolved over time with the red dot representing each year’s mean.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/post/ncaa-conferences_files/figure-html/unnamed-chunk-1-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;It looks like most teams slowly but surely began slowing down overall pace; tempo was trending downwards right until the 2016 season. So, what happened in 2016? The NCAA reduced the shot clock from 35 seconds to 30 and looks to have made an immediate impact on the way teams play. The average team possessions jumped from 64.4 in 2015 to 68.2 in 2016, the highest since 2002. That’s an increase of about 8 more total possessions per game! Next, let’s break it down on the conference level.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;conference-tempo&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Conference Tempo&lt;/h2&gt;
&lt;p&gt;The plot below shows how each of the major conferences transitioned in terms of pace during the five years prior to using a 30 second shot clock and the three years since.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;before &amp;lt;- ncaa %&amp;gt;%
  filter(Conference %in% c(&amp;quot;B10&amp;quot;, &amp;quot;B12&amp;quot;, &amp;quot;P12&amp;quot;, &amp;quot;SEC&amp;quot;, &amp;quot;ACC&amp;quot;, &amp;quot;BE&amp;quot;)) %&amp;gt;%
  filter(year &amp;lt; 2016 &amp;amp; year &amp;gt; 2010) %&amp;gt;%
  group_by(Conference) %&amp;gt;%
  summarise(&amp;quot;30 Seconds&amp;quot; = mean(AdjT))

after &amp;lt;- ncaa %&amp;gt;%
  filter(Conference %in% c(&amp;quot;B10&amp;quot;, &amp;quot;B12&amp;quot;, &amp;quot;P12&amp;quot;, &amp;quot;SEC&amp;quot;, &amp;quot;ACC&amp;quot;, &amp;quot;BE&amp;quot;)) %&amp;gt;%
  filter(year &amp;gt; 2015) %&amp;gt;%
  group_by(Conference) %&amp;gt;%
  summarise(&amp;quot;35 Seconds&amp;quot; = mean(AdjT))

tempo &amp;lt;- full_join(before, after, by = &amp;quot;Conference&amp;quot;) %&amp;gt;% 
  gather(&amp;quot;Shot Clock&amp;quot;, Tempo, 2:3)

tempo$Conference &amp;lt;- recode(tempo$Conference, B10 = &amp;quot;Big 10&amp;quot;, B12 = &amp;quot;Big 12&amp;quot;, P12 = &amp;quot;Pac-12&amp;quot;, BE = &amp;quot;Big East&amp;quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;iframe width=&#34;800&#34; height=&#34;550&#34; frameborder=&#34;0&#34; scrolling=&#34;no&#34; src=&#34;//plot.ly/~bixby96/7.embed?link=false&amp;amp;logo=false&#34;&gt;
&lt;/iframe&gt;
&lt;p&gt;The Big East is no longer a slower paced, defensive-minded conference like the Big 10; they lead all conferences in terms of average tempo using a 30 second shot clock.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;conference-clustering&#34; class=&#34;section level1&#34;&gt;
&lt;h1&gt;Conference Clustering&lt;/h1&gt;
&lt;div id=&#34;high-major-vs.mid-major&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;High-Major vs. Mid-Major&lt;/h2&gt;
&lt;p&gt;Each school competes in one of 32 different conferences which are determined primarily by geography and school size. Not all conferences are created equally, however. At the top of the food chain, “Power Six” conferences (ACC, Big 10, Big 12, Big East, Pac-12, SEC) recruit the top talent year in, year out and are the most competitive each year. The rest of the conferences could be considered “mid-major”, but some like to make the distinction to separate into one more category: “high-major.” They are typically a step above the rest of the mid-majors but aren’t as strong top-to-bottom as the Power Six. Let’s use k-means clustering to determine which conferences deserve the high-major distinction.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;k-means&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;K-means&lt;/h2&gt;
&lt;p&gt;First things first, let’s determine what data to use. &lt;a href=&#34;https://en.wikipedia.org/wiki/2010%E2%80%932014_NCAA_conference_realignment&#34;&gt;Conference realignment&lt;/a&gt; kind of throws a wrench into things, so to get a better idea of the current landscape we’ll focus our efforts only on the past five seasons. We’ll use each conference’s median team offensive and defensive efficiency metric defined as the points scored or allowed per 100 possessions (adjusted for opponent) and tempo (described above) to paint a picture of each conference’s overall skill and style of play. Combining those features let’s determine the optimal number of clusters using silhouette coefficients.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;set.seed(8675309)

kmeans.data &amp;lt;- ncaa %&amp;gt;%
  filter(year &amp;gt; 2013) %&amp;gt;%
  group_by(Conference) %&amp;gt;%
  select(AdjO, AdjD, AdjT) %&amp;gt;%
  summarise_all(median) %&amp;gt;%
  column_to_rownames(&amp;quot;Conference&amp;quot;) %&amp;gt;%
  scale() &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;/post/ncaa-conferences_files/figure-html/optimal%20clusters-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;The optimal number of centers to use for k-means model is 2. The silhouette score measures the separation of each point between clusters. In short, the higher score, the better the clustering result. The silhouette plot with 2 clusters is shown below.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;ncaa.km &amp;lt;- kmeans(kmeans.data, 2, nstart = 33)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;/post/ncaa-conferences_files/figure-html/silhouette%20plots-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;The results of our k-means cluster can be visualized on a PCA biplot showing &lt;code&gt;96.7%&lt;/code&gt; (65.6 + 31.1) of the variability in the data.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/post/ncaa-conferences_files/figure-html/cluster-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Congratulations to members of the American, Atlantic 10, Mountain West, Missouri Valley, and West Coast Conferences. You have officially been promoted to High-Major status! Now of those High-Majors, let’s see which schools could make the jump to a Power Six conference based on recent performance.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;#define conference type
ncaa &amp;lt;- ncaa %&amp;gt;%
  mutate(type = case_when(Conference %in% c(&amp;quot;ACC&amp;quot;, &amp;quot;B10&amp;quot;, &amp;quot;B12&amp;quot;, &amp;quot;P12&amp;quot;, &amp;quot;SEC&amp;quot;, &amp;quot;BE&amp;quot;) ~ &amp;quot;Power 6&amp;quot;,
                          Conference %in% c(&amp;quot;A10&amp;quot;, &amp;quot;Amer&amp;quot;, &amp;quot;MWC&amp;quot;, &amp;quot;MVC&amp;quot;, &amp;quot;WCC&amp;quot;) ~ &amp;quot;High-Major&amp;quot;,
                          TRUE ~ &amp;quot;Mid-Major&amp;quot;)) &lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div id=&#34;the-best-of-the-rest&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;The Best of the Rest&lt;/h2&gt;
&lt;p&gt;Kenpom ranks each team by its efficiency margin which is a team’s offensive minus defensive efficiency. Since 2014, the average efficiency margin for Power Six schools’ is 13.80. During that same time, High-Majors with an overall efficiency margin of that or better are listed below.&lt;/p&gt;
&lt;table class=&#34;table&#34; style=&#34;width: auto !important; margin-left: auto; margin-right: auto;&#34;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&#34;text-align:left;&#34;&gt;
Team
&lt;/th&gt;
&lt;th style=&#34;text-align:right;&#34;&gt;
AdjEM
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Gonzaga
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
24.764
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Wichita St.
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
23.054
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Cincinnati
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
19.846
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
SMU
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
18.098
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Saint Mary’s
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
15.658
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
San Diego St.
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
14.752
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
VCU
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
13.898
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;These schools will most likely be given a hard look from Power Six conferences looking to expand. Gonzaga, Wichita St., and VCU have all made the Final Four this decade as well.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Baseball Ejections and Replay Review</title>
      <link>/mlb-ejections/</link>
      <pubDate>Wed, 03 Oct 2018 00:00:00 +0000</pubDate>
      
      <guid>/mlb-ejections/</guid>
      <description>
&lt;script src=&#34;/rmarkdown-libs/htmlwidgets/htmlwidgets.js&#34;&gt;&lt;/script&gt;
&lt;script src=&#34;/rmarkdown-libs/d3/d3.min.js&#34;&gt;&lt;/script&gt;
&lt;link href=&#34;/rmarkdown-libs/d3tree2/d3tree2.css&#34; rel=&#34;stylesheet&#34; /&gt;
&lt;script src=&#34;/rmarkdown-libs/d3tree2-binding/d3tree2.js&#34;&gt;&lt;/script&gt;
&lt;script src=&#34;/rmarkdown-libs/kePrint/kePrint.js&#34;&gt;&lt;/script&gt;


&lt;p&gt;The 2014 MLB season marked the first time a team could utilize instant replay to challenge an umpire’s ruling. Although technically introduced in 2008, previously only home run boundary calls could be reviewed at an umpire’s discretion. Now with less time spent arguing safe/out calls and more time consulting replay officials in New York, there seems to be less opportunity for players and managers to argue and get ejected. But let’s consult the data first. I looked at ten years of ejection data (2008-2017) coming from &lt;a href=&#34;http://portal.closecallsports.com/&#34;&gt;UEFL Portal&lt;/a&gt; to see if I could reveal any interesting patterns. The steps of my analysis are outlined below.&lt;/p&gt;
&lt;hr /&gt;
&lt;div id=&#34;data-pre-processing&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Data Pre-Processing&lt;/h2&gt;
&lt;div id=&#34;load-packages&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Load Packages&lt;/h3&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;library(tidyverse)
library(readxl)
library(lubridate)
library(jcolors)
library(scales)
library(treemap)
library(d3treeR)
library(kableExtra)
library(ggtern)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div id=&#34;import-data&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Import Data&lt;/h3&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;#load ejections data
load(file = &amp;quot;data/ejections.rda&amp;quot;) &lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div id=&#34;clean-data&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Clean Data&lt;/h3&gt;
&lt;p&gt;The data is stored in a list containing ten data frames, each containing one year’s worth of ejections. As the years progressed, some column names evolved into simpler variable titles such as “Ejected Reason” becoming just “Reason”. I’ll adjust the differing variable names to match the others before combining all ten data frames into one.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;map(ejections, names) #review column names for each yearly dataset

#create function to replace &amp;#39;08-&amp;#39;12 column names
fix_columns &amp;lt;- function(df){
  new_names &amp;lt;- c(&amp;quot;W/L Pre-&amp;quot; = &amp;quot;W/L at time?&amp;quot; , 
                 &amp;quot;W/L Final&amp;quot; =&amp;quot;W/L at final?&amp;quot;,
                 &amp;quot;Ej Pos&amp;quot; = &amp;quot;Pos__1&amp;quot;)
  df %&amp;gt;%
    rename(!!new_names)
}

ejections[6:10] &amp;lt;- map(ejections[6:10], fix_columns)

#create anonymous functions to fix remaining differences
ejections[5:10] &amp;lt;- map(ejections[5:10], function(.x) .x %&amp;gt;% rename(&amp;quot;Name&amp;quot; = &amp;quot;Ejected Name&amp;quot;) %&amp;gt;% rename(&amp;quot;Reason&amp;quot; = &amp;quot;Eject Reason&amp;quot;))
ejections[9:10] &amp;lt;- map(ejections[9:10], function(.x) .x %&amp;gt;% rename(&amp;quot;Team&amp;quot; = &amp;quot;Ej Team&amp;quot;))

#create function to select columns for each dataset in list
select_columns&amp;lt;- function(df){
  df %&amp;gt;%
  filter(`W/L Final` != &amp;quot;NA&amp;quot;) %&amp;gt;%
    select(&amp;quot;Date&amp;quot;, &amp;quot;Team&amp;quot;, &amp;quot;Ej Pos&amp;quot;, &amp;quot;Name&amp;quot;, &amp;quot;H&amp;quot;, &amp;quot;AB&amp;quot;, &amp;quot;W/L Pre-&amp;quot;, &amp;quot;W/L Final&amp;quot;, &amp;quot;RS&amp;quot;, &amp;quot;RA&amp;quot;, &amp;quot;AB&amp;quot;, &amp;quot;Inn&amp;quot;, &amp;quot;Reason&amp;quot;, &amp;quot;Play Result&amp;quot;)
}

ejections &amp;lt;- map(ejections, select_columns)

#combine all years
ejections &amp;lt;- bind_rows(ejections)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From 2008-2017 there were a total of 1930 ejections. A quick snapshot of the data is shown below.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;glimpse(ejections)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## Observations: 1,930
## Variables: 13
## $ Date          &amp;lt;dttm&amp;gt; 2017-04-05, 2017-04-06, 2017-04-09, 2017-04-10, 2…
## $ Team          &amp;lt;chr&amp;gt; &amp;quot;MIA&amp;quot;, &amp;quot;LAD&amp;quot;, &amp;quot;TB&amp;quot;, &amp;quot;PHI&amp;quot;, &amp;quot;COL&amp;quot;, &amp;quot;SEA&amp;quot;, &amp;quot;TEX&amp;quot;, &amp;quot;T…
## $ `Ej Pos`      &amp;lt;chr&amp;gt; &amp;quot;Manager&amp;quot;, &amp;quot;CF&amp;quot;, &amp;quot;CF&amp;quot;, &amp;quot;Manager&amp;quot;, &amp;quot;Manager&amp;quot;, &amp;quot;Mana…
## $ Name          &amp;lt;chr&amp;gt; &amp;quot;Don Mattingly&amp;quot;, &amp;quot;Joc Pederson&amp;quot;, &amp;quot;Kevin Kiermaier&amp;quot;…
## $ H             &amp;lt;dbl&amp;gt; NA, 0, 3, NA, NA, NA, NA, NA, NA, NA, NA, 1, NA, 0…
## $ AB            &amp;lt;dbl&amp;gt; NA, 3, 4, NA, NA, NA, NA, NA, NA, NA, NA, 2, NA, 3…
## $ `W/L Pre-`    &amp;lt;chr&amp;gt; &amp;quot;L&amp;quot;, &amp;quot;W&amp;quot;, &amp;quot;W&amp;quot;, &amp;quot;Tie&amp;quot;, &amp;quot;L&amp;quot;, &amp;quot;L&amp;quot;, &amp;quot;L&amp;quot;, &amp;quot;L&amp;quot;, &amp;quot;L&amp;quot;, &amp;quot;L&amp;quot;…
## $ `W/L Final`   &amp;lt;chr&amp;gt; &amp;quot;L&amp;quot;, &amp;quot;W&amp;quot;, &amp;quot;W&amp;quot;, &amp;quot;L&amp;quot;, &amp;quot;L&amp;quot;, &amp;quot;W&amp;quot;, &amp;quot;L&amp;quot;, &amp;quot;W&amp;quot;, &amp;quot;L&amp;quot;, &amp;quot;L&amp;quot;, …
## $ RS            &amp;lt;dbl&amp;gt; 2, 0, 2, 1, 2, 3, 1, 2, 0, 0, 2, 2, 0, 2, 2, 6, 0,…
## $ RA            &amp;lt;dbl&amp;gt; 0, 0, 0, 2, 4, 1, 5, 0, 2, 0, 2, 2, 2, 2, 2, 2, 1,…
## $ Inn           &amp;lt;dbl&amp;gt; 7, 7, 7, 8, 5, 6, 3, 9, 8, 8, 5, 5, 8, 7, 7, 3, 7,…
## $ Reason        &amp;lt;chr&amp;gt; &amp;quot;Unsportsmanlike-NEC&amp;quot;, &amp;quot;Balls/Strikes&amp;quot;, &amp;quot;Balls/Str…
## $ `Play Result` &amp;lt;chr&amp;gt; &amp;quot;HBP&amp;quot;, &amp;quot;K&amp;quot;, &amp;quot;K&amp;quot;, &amp;quot;Ball&amp;quot;, &amp;quot;No Balk&amp;quot;, &amp;quot;Fair&amp;quot;, &amp;quot;Foul&amp;quot;…&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After a few more housekeeping data manipulations, I think our data is ready to be explored!&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;#convert from DateTime to Date
ejections$Date &amp;lt;- ymd(ejections$Date)

#Create Year variable
ejections$Year &amp;lt;- year(ejections$Date)

#adjust differing team name abbreviations
ejections$Team &amp;lt;-
  fct_recode(ejections$Team, MIA = &amp;quot;FLA&amp;quot;, ARI = &amp;quot;AZ&amp;quot;, MIA = &amp;quot;FL&amp;quot;, WAS = &amp;quot;WSH&amp;quot;)

#Check swing ejections were not differentiated from ball/strikes until 2014
ejections$Reason &amp;lt;- fct_recode(ejections$Reason, `Balls/Strikes` = &amp;quot;Check Swing&amp;quot;)

#recode levels
ejections$`W/L Pre-` &amp;lt;- recode(ejections$`W/L Pre-`, L = -1, Tie = 0, TIe = 0, W = 1) 
ejections$`W/L Final` &amp;lt;- recode(ejections$`W/L Final`, L = -1, W = 1)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;ejections-by-year-cause&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Ejections By Year &amp;amp; Cause&lt;/h2&gt;
&lt;p&gt;First let’s take a look at how ejections have changed since replay was introduced in 2014.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/post/mlb-ejections_files/figure-html/unnamed-chunk-5-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;From 2008 to 2017, an MLB season averaged 193 ejections per season. In 2014, the first year of expanded replay, the number of ejections increased by 21, eclipsing 200. The following year saw yet another jump, before dropping below the 10-year average in ’16 and ’17. While the replay system doesn’t appear to be deterring ejections, I wouldn’t say it’s encouraging them either. What could be changing; however, is the reason for players/coaches getting ejected. Let’s look at how the cause of arguments could be evolving.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;ejections$Reason &amp;lt;- fct_other(ejections$Reason, keep = c(&amp;quot;Balls/Strikes&amp;quot;, &amp;quot;Fighting&amp;quot;, &amp;quot;Replay Review&amp;quot;, &amp;quot;Safe/Out&amp;quot;, &amp;quot;Throwing At&amp;quot;))

data &amp;lt;- ejections %&amp;gt;%
  group_by(Year, Reason) %&amp;gt;%
  select(Year, Reason) %&amp;gt;%
  add_tally() %&amp;gt;%
  distinct() %&amp;gt;%
  group_by(Year) %&amp;gt;%
  mutate(percent = n/sum(n)) %&amp;gt;%
  group_by(Year, Reason) %&amp;gt;%
  summarise(percent = sum(percent)) %&amp;gt;%
  ungroup() %&amp;gt;%
  add_row(Year = 2008:2013, Reason = &amp;quot;Replay Review&amp;quot;, percent = 0) %&amp;gt;%
  add_row(Year = 2016:2017, Reason = &amp;quot;Safe/Out&amp;quot;, percent = 0)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;/post/mlb-ejections_files/figure-html/unnamed-chunk-7-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Arguing safe/out sharply declined after having the ability to challenge calls before going extinct in 2016. A new type of ejection emerged as a result though. Issues with the replay ruling or why a challenge was or was not granted seemed to fill the gap. The “other” category refers to play regarding interference, balks, or any other less common ruling. Perhaps what is most noteworthy, is that from 2013 to 2017 the percentage of yearly ejections via arguing balls/strikes (which also includes check swings) is up 17%. The trust in an umpire’s ability to manage the strike zone seems to be at least shrinking some. If that number doesn’t decrease anytime soon, I wouldn’t be surprised to see the automated strike zone make its debut sooner rather than later.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;ejections-by-division&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Ejections By Division&lt;/h2&gt;
&lt;p&gt;The following chart outlines the total amount of ejections by division. Try clicking on each square to explore which teams contribute the most to their respective divisions total and hover over each to see their count.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;divisions &amp;lt;- ejections %&amp;gt;%
  mutate(division = case_when(Team %in% c(&amp;quot;STL&amp;quot;, &amp;quot;CHC&amp;quot;, &amp;quot;MIL&amp;quot;, &amp;quot;CIN&amp;quot;, &amp;quot;PIT&amp;quot;) ~ &amp;quot;NL Central&amp;quot;,
                              Team %in% c(&amp;quot;LAD&amp;quot;, &amp;quot;SF&amp;quot;, &amp;quot;SD&amp;quot;, &amp;quot;COL&amp;quot;, &amp;quot;ARI&amp;quot;) ~ &amp;quot;NL West&amp;quot;,
                              Team %in% c(&amp;quot;MIA&amp;quot;, &amp;quot;PHI&amp;quot;, &amp;quot;WAS&amp;quot;, &amp;quot;NYM&amp;quot;, &amp;quot;ATL&amp;quot;) ~ &amp;quot;NL East&amp;quot;,
                              Team %in% c(&amp;quot;NYY&amp;quot;, &amp;quot;BOS&amp;quot;, &amp;quot;TB&amp;quot;, &amp;quot;TOR&amp;quot;, &amp;quot;BAL&amp;quot;) ~ &amp;quot;AL East&amp;quot;,
                              Team %in% c(&amp;quot;LAA&amp;quot;, &amp;quot;HOU&amp;quot;, &amp;quot;OAK&amp;quot;, &amp;quot;TEX&amp;quot;, &amp;quot;SEA&amp;quot;) ~ &amp;quot;AL West&amp;quot;,
                              Team %in% c(&amp;quot;CWS&amp;quot;, &amp;quot;DET&amp;quot;, &amp;quot;KC&amp;quot;, &amp;quot;CLE&amp;quot;, &amp;quot;MIN&amp;quot;) ~ &amp;quot;AL Central&amp;quot;)) %&amp;gt;%
  group_by(Team, division) %&amp;gt;%
  count()&lt;/code&gt;&lt;/pre&gt;
&lt;div id=&#34;htmlwidget-1&#34; style=&#34;width:672px;height:480px;&#34; class=&#34;d3tree2 html-widget&#34;&gt;&lt;/div&gt;
&lt;script type=&#34;application/json&#34; data-for=&#34;htmlwidget-1&#34;&gt;{&#34;x&#34;:{&#34;data&#34;:{&#34;name&#34;:&#34;Ejections by Division (2008-2017)&#34;,&#34;id&#34;:1,&#34;size&#34;:null,&#34;children&#34;:[{&#34;name&#34;:&#34;AL Central&#34;,&#34;color&#34;:&#34;#66C2A5&#34;,&#34;h&#34;:0.464088397790055,&#34;id&#34;:2,&#34;size&#34;:336,&#34;stdErr&#34;:336,&#34;vColor&#34;:5,&#34;vSize&#34;:336,&#34;w&#34;:0.375129533678756,&#34;x0&#34;:0,&#34;y0&#34;:0,&#34;children&#34;:[{&#34;name&#34;:&#34;CLE&#34;,&#34;color&#34;:&#34;#4BAF7F&#34;,&#34;h&#34;:0.140305794680714,&#34;id&#34;:3,&#34;size&#34;:52,&#34;stdErr&#34;:52,&#34;vColor&#34;:1,&#34;vSize&#34;:52,&#34;w&#34;:0.192030594621268,&#34;x0&#34;:0.183098939057488,&#34;y0&#34;:0},{&#34;name&#34;:&#34;CWS&#34;,&#34;color&#34;:&#34;#4BAF87&#34;,&#34;h&#34;:0.209405740466244,&#34;id&#34;:4,&#34;size&#34;:74,&#34;stdErr&#34;:74,&#34;vColor&#34;:1,&#34;vSize&#34;:74,&#34;w&#34;:0.183098939057488,&#34;x0&#34;:0,&#34;y0&#34;:0},{&#34;name&#34;:&#34;DET&#34;,&#34;color&#34;:&#34;#4BAF8F&#34;,&#34;h&#34;:0.254682657323811,&#34;id&#34;:5,&#34;size&#34;:90,&#34;stdErr&#34;:90,&#34;vColor&#34;:1,&#34;vSize&#34;:90,&#34;w&#34;:0.183098939057488,&#34;x0&#34;:0,&#34;y0&#34;:0.209405740466244},{&#34;name&#34;:&#34;KC&#34;,&#34;color&#34;:&#34;#4BAF98&#34;,&#34;h&#34;:0.172684054991648,&#34;id&#34;:6,&#34;size&#34;:64,&#34;stdErr&#34;:64,&#34;vColor&#34;:1,&#34;vSize&#34;:64,&#34;w&#34;:0.192030594621268,&#34;x0&#34;:0.183098939057488,&#34;y0&#34;:0.291404342798407},{&#34;name&#34;:&#34;MIN&#34;,&#34;color&#34;:&#34;#4BAFA0&#34;,&#34;h&#34;:0.151098548117692,&#34;id&#34;:7,&#34;size&#34;:56,&#34;stdErr&#34;:56,&#34;vColor&#34;:1,&#34;vSize&#34;:56,&#34;w&#34;:0.192030594621268,&#34;x0&#34;:0.183098939057488,&#34;y0&#34;:0.140305794680714}]},{&#34;name&#34;:&#34;AL East&#34;,&#34;color&#34;:&#34;#FC8D62&#34;,&#34;h&#34;:0.535911602209945,&#34;id&#34;:8,&#34;size&#34;:388,&#34;stdErr&#34;:388,&#34;vColor&#34;:5,&#34;vSize&#34;:388,&#34;w&#34;:0.375129533678756,&#34;x0&#34;:0,&#34;y0&#34;:0.464088397790055,&#34;children&#34;:[{&#34;name&#34;:&#34;BAL&#34;,&#34;color&#34;:&#34;#E34F3C&#34;,&#34;h&#34;:0.150809295094256,&#34;id&#34;:9,&#34;size&#34;:56,&#34;stdErr&#34;:56,&#34;vColor&#34;:1,&#34;vSize&#34;:56,&#34;w&#34;:0.19239891031462,&#34;x0&#34;:0.182730623364137,&#34;y0&#34;:0.464088397790055},{&#34;name&#34;:&#34;BOS&#34;,&#34;color&#34;:&#34;#E35D3C&#34;,&#34;h&#34;:0.269373556666374,&#34;id&#34;:10,&#34;size&#34;:95,&#34;stdErr&#34;:95,&#34;vColor&#34;:1,&#34;vSize&#34;:95,&#34;w&#34;:0.182730623364137,&#34;x0&#34;:0,&#34;y0&#34;:0.730626443333626},{&#34;name&#34;:&#34;NYY&#34;,&#34;color&#34;:&#34;#E36B3C&#34;,&#34;h&#34;:0.183125572614453,&#34;id&#34;:11,&#34;size&#34;:68,&#34;stdErr&#34;:68,&#34;vColor&#34;:1,&#34;vSize&#34;:68,&#34;w&#34;:0.19239891031462,&#34;x0&#34;:0.182730623364137,&#34;y0&#34;:0.614897692884311},{&#34;name&#34;:&#34;TB&#34;,&#34;color&#34;:&#34;#E3793C&#34;,&#34;h&#34;:0.201976734501235,&#34;id&#34;:12,&#34;size&#34;:75,&#34;stdErr&#34;:75,&#34;vColor&#34;:1,&#34;vSize&#34;:75,&#34;w&#34;:0.19239891031462,&#34;x0&#34;:0.182730623364137,&#34;y0&#34;:0.798023265498765},{&#34;name&#34;:&#34;TOR&#34;,&#34;color&#34;:&#34;#E3873C&#34;,&#34;h&#34;:0.26653804554357,&#34;id&#34;:13,&#34;size&#34;:94,&#34;stdErr&#34;:94,&#34;vColor&#34;:1,&#34;vSize&#34;:94,&#34;w&#34;:0.182730623364137,&#34;x0&#34;:0,&#34;y0&#34;:0.464088397790055}]},{&#34;name&#34;:&#34;AL West&#34;,&#34;color&#34;:&#34;#8DA0CB&#34;,&#34;h&#34;:0.48424543946932,&#34;id&#34;:14,&#34;size&#34;:285,&#34;stdErr&#34;:285,&#34;vColor&#34;:5,&#34;vSize&#34;:285,&#34;w&#34;:0.304945347434169,&#34;x0&#34;:0.695054652565831,&#34;y0&#34;:0,&#34;children&#34;:[{&#34;name&#34;:&#34;HOU&#34;,&#34;color&#34;:&#34;#7493B7&#34;,&#34;h&#34;:0.227680311890838,&#34;id&#34;:15,&#34;size&#34;:63,&#34;stdErr&#34;:63,&#34;vColor&#34;:1,&#34;vSize&#34;:63,&#34;w&#34;:0.14336982752502,&#34;x0&#34;:0.85663017247498,&#34;y0&#34;:0.256565127578482},{&#34;name&#34;:&#34;LAA&#34;,&#34;color&#34;:&#34;#748EB7&#34;,&#34;h&#34;:0.256565127578482,&#34;id&#34;:16,&#34;size&#34;:50,&#34;stdErr&#34;:50,&#34;vColor&#34;:1,&#34;vSize&#34;:50,&#34;w&#34;:0.100975280607341,&#34;x0&#34;:0.8101664724582,&#34;y0&#34;:0},{&#34;name&#34;:&#34;OAK&#34;,&#34;color&#34;:&#34;#7488B7&#34;,&#34;h&#34;:0.256565127578482,&#34;id&#34;:17,&#34;size&#34;:57,&#34;stdErr&#34;:57,&#34;vColor&#34;:1,&#34;vSize&#34;:57,&#34;w&#34;:0.115111819892368,&#34;x0&#34;:0.695054652565831,&#34;y0&#34;:0},{&#34;name&#34;:&#34;SEA&#34;,&#34;color&#34;:&#34;#7483B7&#34;,&#34;h&#34;:0.256565127578482,&#34;id&#34;:18,&#34;size&#34;:44,&#34;stdErr&#34;:44,&#34;vColor&#34;:1,&#34;vSize&#34;:44,&#34;w&#34;:0.0888582469344597,&#34;x0&#34;:0.91114175306554,&#34;y0&#34;:0},{&#34;name&#34;:&#34;TEX&#34;,&#34;color&#34;:&#34;#747DB7&#34;,&#34;h&#34;:0.227680311890838,&#34;id&#34;:19,&#34;size&#34;:71,&#34;stdErr&#34;:71,&#34;vColor&#34;:1,&#34;vSize&#34;:71,&#34;w&#34;:0.161575519909149,&#34;x0&#34;:0.695054652565831,&#34;y0&#34;:0.256565127578482}]},{&#34;name&#34;:&#34;NL Central&#34;,&#34;color&#34;:&#34;#E78AC3&#34;,&#34;h&#34;:0.51575456053068,&#34;id&#34;:20,&#34;size&#34;:299,&#34;stdErr&#34;:299,&#34;vColor&#34;:5,&#34;vSize&#34;:299,&#34;w&#34;:0.300379854389151,&#34;x0&#34;:0.699620145610849,&#34;y0&#34;:0.48424543946932,&#34;children&#34;:[{&#34;name&#34;:&#34;CHC&#34;,&#34;color&#34;:&#34;#D06BBA&#34;,&#34;h&#34;:0.239765498039346,&#34;id&#34;:21,&#34;size&#34;:65,&#34;stdErr&#34;:65,&#34;vColor&#34;:1,&#34;vSize&#34;:65,&#34;w&#34;:0.140465399534495,&#34;x0&#34;:0.859534600465505,&#34;y0&#34;:0.760234501960654},{&#34;name&#34;:&#34;CIN&#34;,&#34;color&#34;:&#34;#D06BB1&#34;,&#34;h&#34;:0.275989062491334,&#34;id&#34;:22,&#34;size&#34;:54,&#34;stdErr&#34;:54,&#34;vColor&#34;:1,&#34;vSize&#34;:54,&#34;w&#34;:0.101378200856338,&#34;x0&#34;:0.806630468736984,&#34;y0&#34;:0.48424543946932},{&#34;name&#34;:&#34;MIL&#34;,&#34;color&#34;:&#34;#D06BA9&#34;,&#34;h&#34;:0.275989062491334,&#34;id&#34;:23,&#34;size&#34;:57,&#34;stdErr&#34;:57,&#34;vColor&#34;:1,&#34;vSize&#34;:57,&#34;w&#34;:0.107010323126135,&#34;x0&#34;:0.699620145610849,&#34;y0&#34;:0.48424543946932},{&#34;name&#34;:&#34;PIT&#34;,&#34;color&#34;:&#34;#D06BA1&#34;,&#34;h&#34;:0.239765498039346,&#34;id&#34;:24,&#34;size&#34;:74,&#34;stdErr&#34;:74,&#34;vColor&#34;:1,&#34;vSize&#34;:74,&#34;w&#34;:0.159914454854656,&#34;x0&#34;:0.699620145610849,&#34;y0&#34;:0.760234501960654},{&#34;name&#34;:&#34;STL&#34;,&#34;color&#34;:&#34;#D06B98&#34;,&#34;h&#34;:0.275989062491334,&#34;id&#34;:25,&#34;size&#34;:49,&#34;stdErr&#34;:49,&#34;vColor&#34;:1,&#34;vSize&#34;:49,&#34;w&#34;:0.0919913304066775,&#34;x0&#34;:0.908008669593323,&#34;y0&#34;:0.48424543946932}]},{&#34;name&#34;:&#34;NL East&#34;,&#34;color&#34;:&#34;#A6D854&#34;,&#34;h&#34;:0.51575456053068,&#34;id&#34;:26,&#34;size&#34;:323,&#34;stdErr&#34;:323,&#34;vColor&#34;:5,&#34;vSize&#34;:323,&#34;w&#34;:0.324490611932093,&#34;x0&#34;:0.375129533678756,&#34;y0&#34;:0.48424543946932,&#34;children&#34;:[{&#34;name&#34;:&#34;ATL&#34;,&#34;color&#34;:&#34;#A4C234&#34;,&#34;h&#34;:0.237917738449137,&#34;id&#34;:27,&#34;size&#34;:82,&#34;stdErr&#34;:82,&#34;vColor&#34;:1,&#34;vSize&#34;:82,&#34;w&#34;:0.178578726029742,&#34;x0&#34;:0.375129533678756,&#34;y0&#34;:0.762082261550863},{&#34;name&#34;:&#34;MIA&#34;,&#34;color&#34;:&#34;#98C234&#34;,&#34;h&#34;:0.277836822081543,&#34;id&#34;:28,&#34;size&#34;:60,&#34;stdErr&#34;:60,&#34;vColor&#34;:1,&#34;vSize&#34;:60,&#34;w&#34;:0.111893314459342,&#34;x0&#34;:0.490752625286744,&#34;y0&#34;:0.48424543946932},{&#34;name&#34;:&#34;NYM&#34;,&#34;color&#34;:&#34;#8CC234&#34;,&#34;h&#34;:0.277836822081543,&#34;id&#34;:29,&#34;size&#34;:62,&#34;stdErr&#34;:62,&#34;vColor&#34;:1,&#34;vSize&#34;:62,&#34;w&#34;:0.115623091607987,&#34;x0&#34;:0.375129533678756,&#34;y0&#34;:0.48424543946932},{&#34;name&#34;:&#34;PHI&#34;,&#34;color&#34;:&#34;#81C234&#34;,&#34;h&#34;:0.277836822081543,&#34;id&#34;:30,&#34;size&#34;:52,&#34;stdErr&#34;:52,&#34;vColor&#34;:1,&#34;vSize&#34;:52,&#34;w&#34;:0.0969742058647634,&#34;x0&#34;:0.602645939746086,&#34;y0&#34;:0.48424543946932},{&#34;name&#34;:&#34;WAS&#34;,&#34;color&#34;:&#34;#75C234&#34;,&#34;h&#34;:0.237917738449137,&#34;id&#34;:31,&#34;size&#34;:67,&#34;stdErr&#34;:67,&#34;vColor&#34;:1,&#34;vSize&#34;:67,&#34;w&#34;:0.14591188590235,&#34;x0&#34;:0.553708259708499,&#34;y0&#34;:0.762082261550863}]},{&#34;name&#34;:&#34;NL West&#34;,&#34;color&#34;:&#34;#FFD92F&#34;,&#34;h&#34;:0.48424543946932,&#34;id&#34;:32,&#34;size&#34;:299,&#34;stdErr&#34;:299,&#34;vColor&#34;:5,&#34;vSize&#34;:299,&#34;w&#34;:0.319925118887075,&#34;x0&#34;:0.375129533678756,&#34;y0&#34;:0,&#34;children&#34;:[{&#34;name&#34;:&#34;ARI&#34;,&#34;color&#34;:&#34;#E69705&#34;,&#34;h&#34;:0.246171594646611,&#34;id&#34;:33,&#34;size&#34;:50,&#34;stdErr&#34;:50,&#34;vColor&#34;:1,&#34;vSize&#34;:50,&#34;w&#34;:0.105238525949696,&#34;x0&#34;:0.48457760066644,&#34;y0&#34;:0},{&#34;name&#34;:&#34;COL&#34;,&#34;color&#34;:&#34;#E6AA05&#34;,&#34;h&#34;:0.246171594646611,&#34;id&#34;:34,&#34;size&#34;:50,&#34;stdErr&#34;:50,&#34;vColor&#34;:1,&#34;vSize&#34;:50,&#34;w&#34;:0.105238525949696,&#34;x0&#34;:0.589816126616136,&#34;y0&#34;:0},{&#34;name&#34;:&#34;LAD&#34;,&#34;color&#34;:&#34;#E6BC05&#34;,&#34;h&#34;:0.238073844822709,&#34;id&#34;:35,&#34;size&#34;:89,&#34;stdErr&#34;:89,&#34;vColor&#34;:1,&#34;vSize&#34;:89,&#34;w&#34;:0.193696160414624,&#34;x0&#34;:0.375129533678756,&#34;y0&#34;:0.246171594646611},{&#34;name&#34;:&#34;SD&#34;,&#34;color&#34;:&#34;#E6CF05&#34;,&#34;h&#34;:0.238073844822709,&#34;id&#34;:36,&#34;size&#34;:58,&#34;stdErr&#34;:58,&#34;vColor&#34;:1,&#34;vSize&#34;:58,&#34;w&#34;:0.126228958472451,&#34;x0&#34;:0.56882569409338,&#34;y0&#34;:0.246171594646611},{&#34;name&#34;:&#34;SF&#34;,&#34;color&#34;:&#34;#E6E205&#34;,&#34;h&#34;:0.246171594646611,&#34;id&#34;:37,&#34;size&#34;:52,&#34;stdErr&#34;:52,&#34;vColor&#34;:1,&#34;vSize&#34;:52,&#34;w&#34;:0.109448066987684,&#34;x0&#34;:0.375129533678756,&#34;y0&#34;:0}]}]},&#34;meta&#34;:{&#34;type&#34;:&#34;index&#34;,&#34;vSize&#34;:&#34;n&#34;,&#34;vColor&#34;:null,&#34;stdErr&#34;:&#34;n&#34;,&#34;algorithm&#34;:&#34;pivotSize&#34;,&#34;vpCoorX&#34;:[0.0281214848143982,0.971878515185602],&#34;vpCoorY&#34;:[0.0196850393700787,0.910314960629921],&#34;aspRatio&#34;:1.48351162585094,&#34;range&#34;:null,&#34;mapping&#34;:[null,null,null],&#34;draw&#34;:true},&#34;legend&#34;:null,&#34;options&#34;:{&#34;celltext&#34;:&#34;name&#34;,&#34;id&#34;:&#34;id&#34;,&#34;valueField&#34;:&#34;size&#34;,&#34;clickAction&#34;:null}},&#34;evals&#34;:[],&#34;jsHooks&#34;:[]}&lt;/script&gt;
&lt;p&gt;The most penalized division is the AL East with 388 ejections over 10 years. On average a team will receive 6.43 ejections per season. The top five teams with the most ejections since ’08 are listed below.&lt;/p&gt;
&lt;table class=&#34;table&#34; style=&#34;width: auto !important; margin-left: auto; margin-right: auto;&#34;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&#34;text-align:left;&#34;&gt;
Team
&lt;/th&gt;
&lt;th style=&#34;text-align:left;&#34;&gt;
division
&lt;/th&gt;
&lt;th style=&#34;text-align:right;&#34;&gt;
n
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
BOS
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
AL East
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
95
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
TOR
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
AL East
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
94
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
DET
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
AL Central
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
90
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
LAD
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
NL West
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
89
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
ATL
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
NL East
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
82
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div id=&#34;managerial-ejections&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Managerial Ejections&lt;/h2&gt;
&lt;p&gt;It’s often said during a broadcast that after a manager is ejected, they’ll pay attention to how the players respond. The team will either take the lead (positive outcome), lose the lead (negative outcome), or remain ahead/behind (neutral outcome). The graph below plots all outcomes against each other among managers with 6 or more ejections over the past 10 years.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;ejections$Name &amp;lt;- recode(ejections$Name, &amp;quot;A.J. Hinch&amp;quot; = &amp;quot;AJ Hinch&amp;quot;, &amp;quot;Fredi Gonzales&amp;quot; = &amp;quot;Fredi Gonzalez&amp;quot;)

manager_ej &amp;lt;- ejections %&amp;gt;%
  filter(`Ej Pos` == &amp;quot;Manager&amp;quot;) %&amp;gt;%
  mutate(result = case_when(.$`W/L Final` &amp;gt; .$`W/L Pre-` ~ &amp;quot;Positive&amp;quot;,
                            .$`W/L Final` &amp;lt; .$`W/L Pre-` ~ &amp;quot;Negative&amp;quot;,
                            .$`W/L Final` == .$`W/L Pre-` ~ &amp;quot;Neutral&amp;quot;)) %&amp;gt;%
  group_by(Name, result) %&amp;gt;%
  count() %&amp;gt;%
  spread(result, n, fill =0) %&amp;gt;%
  mutate(total = sum(Positive, Negative, Neutral)) %&amp;gt;%
  filter(total &amp;gt; 6) %&amp;gt;%
  mutate(diff = abs(Positive - Negative)/total)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;/post/mlb-ejections_files/figure-html/unnamed-chunk-13-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;After a team’s manager has been ejected, the current result of the game rarely changes, meaning the team in the lead tends to hang on for the victory. Some managers like Joe Girardi, Bobby Cox, or Bruce Bochy have seen their teams rally to a win in their absence more often than seeing a lead slip away or losing a tied game while others like Jim Riggleman haven’t been so lucky.&lt;/p&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Avocado Market Research</title>
      <link>/avocado-market-research/</link>
      <pubDate>Thu, 13 Sep 2018 00:00:00 +0000</pubDate>
      
      <guid>/avocado-market-research/</guid>
      <description>


&lt;p&gt;The following report intends to analyze avocado prices and sales volume from 2015 to early 2018 across the US. In addition to a thorough exploratory analysis, I’ll also try to calculate the price elasticity of demand for each individual market. The dataset comes from the &lt;a href=&#34;http://www.hassavocadoboard.com/&#34;&gt;Hass Avocado Board&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;div id=&#34;data-pre-processing&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Data Pre-Processing&lt;/h2&gt;
&lt;div id=&#34;load-data&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Load Data&lt;/h3&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;#load avocado data
load(&amp;quot;data/avocados.Rda&amp;quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div id=&#34;load-packages&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Load Packages&lt;/h3&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;library(tidyverse)
library(scales)
library(plotly)
library(wesanderson)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div id=&#34;clean-data&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Clean Data&lt;/h3&gt;
&lt;p&gt;The dataset contains weekly average prices and total amount sold for both organic and conventional avocados for 45 different markets (New York, Boise, St. Louis, etc.) that make up 8 larger regions (California, Great Lakes, Midsouth, Northeast, Plains, South Central, Southeast, and West). I’ll create three different datasets: one containing the 45 markets, one for the 8 larger regions, and one for entire US. Also, three price lookup codes (PLU’s) are listed, but for Hass avocados only, so I’ll create another variable to hold the rest of avocados (e.g. green-skinned) sold per week.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;#replace spaces with underscores in column names
names(avocados) &amp;lt;- gsub(&amp;quot; &amp;quot;, &amp;quot;_&amp;quot;, names(avocados))

#rename PLU codes and tidy up data
avocados &amp;lt;- avocados %&amp;gt;%
  rename(small_hass = &amp;quot;4046&amp;quot;, large_hass = &amp;quot;4225&amp;quot;, xl_hass = &amp;quot;4770&amp;quot;) %&amp;gt;%
  mutate(other = Total_Volume - small_hass - large_hass - xl_hass) %&amp;gt;%
  gather(bag_size, bag_total, c(Small_Bags, Large_Bags, XLarge_Bags)) %&amp;gt;%
  gather(avocado_type, avocado_volume, c(small_hass, large_hass, xl_hass,
                                         other)) 

#subset data by region
avocados_region &amp;lt;- avocados %&amp;gt;%
  filter(region %in% c(&amp;quot;California&amp;quot;, &amp;quot;West&amp;quot;, &amp;quot;SouthCentral&amp;quot;, &amp;quot;GreatLakes&amp;quot;,
                       &amp;quot;Midsouth&amp;quot;, &amp;quot;Southeast&amp;quot;, &amp;quot;Northeast&amp;quot;, &amp;quot;Plains&amp;quot;)) 

#subset data by market (city)
avocados_market &amp;lt;- avocados %&amp;gt;%
  filter(!(region %in% c(&amp;quot;California&amp;quot;, &amp;quot;West&amp;quot;, &amp;quot;SouthCentral&amp;quot;, &amp;quot;GreatLakes&amp;quot;,
                       &amp;quot;Midsouth&amp;quot;, &amp;quot;Southeast&amp;quot;, &amp;quot;Northeast&amp;quot;, &amp;quot;Plains&amp;quot;,
                       &amp;quot;TotalUS&amp;quot;)))

#dataset for entire US
avocados_total &amp;lt;- avocados %&amp;gt;%
  filter(region == &amp;quot;TotalUS&amp;quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let’s make sure we don’t have any missing values&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;paste(sum(is.na(avocados_market)),
sum(is.na(avocados_region)),
sum(is.na(avocados_total)))&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## [1] &amp;quot;0 0 0&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bravocado! Also, let’s see if there are any hidden markets that make up a region.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;cat(paste(&amp;quot;Market Volume:&amp;quot;,
sum(avocados_market$avocado_volume),&amp;quot;\n&amp;quot;),
paste(&amp;quot;Region Volume:&amp;quot;,
sum(avocados_region$avocado_volume), &amp;quot;\n&amp;quot;),
paste(&amp;quot;Total Volume:&amp;quot;,
sum(avocados_total$avocado_volume)))&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## Market Volume: 11381766688.74 
##  Region Volume: 17594220546.06 
##  Total Volume: 17594220545.4&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So it looks like some avocados (6,212,453,857 to be exact) were sold over the past few years in markets not found in the dataset. But the eight regions do in fact contain the entirety of US avocado sales (minus rounding error).&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;exploratory-data-analysis&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Exploratory Data Analysis&lt;/h2&gt;
&lt;div id=&#34;distribution&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Distribution&lt;/h3&gt;
&lt;p&gt;Alright now that we understand the data, I think it’s time for some exploratory data analysis! First, let’s look at how the prices of organic and conventional avocados are distributed.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/post/avocados_files/figure-html/plots-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Not surprisingly, organic avocados are generally priced higher than conventional ones. The dashed vertical line in the middle represents the average weekly price for all avocados, $1.37. Next, let’s look at how prices have varied over time.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;avocado-prices&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Avocado Prices&lt;/h3&gt;
&lt;iframe width=&#34;800&#34; height=&#34;550&#34; frameborder=&#34;0&#34; scrolling=&#34;no&#34; src=&#34;//plot.ly/~bixby96/9.embed?link=false&amp;amp;logo=false&#34;&gt;
&lt;/iframe&gt;
&lt;p&gt;A couple of things stick out to me. Avocados reached a 3-year high in late summer 2017. Also the apocalyptic organic price drop around July 2015. My guess is that there was some missing data for US total organic avocado prices in July 2015 that got imputed as $1.00. Let’s check the price movement for each region to see if any sharp declines in July 2015 exist.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/post/avocados_files/figure-html/unnamed-chunk-3-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Nothing out of the ordinary here. Organic prices never dropped below conventional prices in each region. I will just leave the US dataset as is and focus the rest of my analysis on the region dataset. Now, let’s see how avocado prices vary across regions.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/post/avocados_files/figure-html/unnamed-chunk-4-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;The Northeast region sells avocados at the highest average price. Now, let’s determine which size of avocados each region buys.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;avocado-volume&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Avocado Volume&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;/post/avocados_files/figure-html/unnamed-chunk-5-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;The South Central, California, and West regions make up the three largest avocado regions by volume. The Northeast region sells the most Large Hass avocados (both proportionally to total regional sales and overall) which probably contributes to them having the highest average price. With that said, let’s look at how each market consumes avocados.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/post/avocados_files/figure-html/unnamed-chunk-6-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;The LA market appears to be ripe for avocados; it doubles the second largest market (New York) in terms of volume. Avocados seem to be most popular in western or warm weathered markets. Even smaller markets like Denver and Portland rank near the top among the larger US cities suggesting avocado consumption has a geographical element to it.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;elasticity&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Elasticity&lt;/h2&gt;
&lt;p&gt;Finally let’s look at the price elasticity of avocados. We can try to determine which markets avocados are the most price elastic. First, let’s plot total volume against average price for all avocados.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/post/avocados_files/figure-html/unnamed-chunk-7-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Conventional avocados appear to show a linear relationship. It’s hard to make up the shape for the organic avocados so let’s try plotting each type in its own graph. It’s also worth noting that organic avocados are sold in much lower volumes than conventional avocados.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/post/avocados_files/figure-html/unnamed-chunk-8-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;It looks like the organic avocado price vs. sales relationship is more uniform, hinting that it has a less elastic demand than conventional avocados. The linear model seems to do an adequate job of describing the data so, for simplicity, let’s just fit a linear price-response function for all markets and compare their overall elasticities.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;elas &amp;lt;- lapply(unique(avocados_market$region), function(b){
            df &amp;lt;- avocados_market %&amp;gt;%
              filter(region == b)
            m &amp;lt;- lm(Total_Volume ~ AveragePrice, data = df)
            x &amp;lt;- m$coefficients[[&amp;quot;AveragePrice&amp;quot;]]
            y &amp;lt;- mean(df$AveragePrice)
            z &amp;lt;- mean(df$Total_Volume)
            x*y/z
        })

elas &amp;lt;- do.call(rbind, elas) %&amp;gt;%
  data.frame() %&amp;gt;%
  mutate(market = unique(avocados_market$region)) %&amp;gt;%
  mutate(elasticity = round(., 2)) %&amp;gt;%
  select(-c(.))&lt;/code&gt;&lt;/pre&gt;
&lt;iframe width=&#34;700&#34; height=&#34;700&#34; frameborder=&#34;0&#34; scrolling=&#34;no&#34; src=&#34;//plot.ly/~bixby96/15.embed?link=false&amp;amp;logo=false&#34;&gt;
&lt;/iframe&gt;
&lt;p&gt;The overall demand for avocados is elastic in all markets. Western markets (especially the Pacific Northwest) are typically less responsive to changes in price than eastern markets. A 10% price increase would cause an 18% drop in demand in Seattle but a 37% drop in New York. The &lt;em&gt;Pit&lt;/em&gt;tsburgh market could very well be immune to the avocado craze as a 10% price increase would decrease demand by &lt;strong&gt;58%&lt;/strong&gt;, 20% more than the next closest market, fellow Pennsylvanian city, Philadelphia.&lt;/p&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>The NFL, NBA, &amp; MLB&#39;s Center of Gravity</title>
      <link>/center-of-gravity/</link>
      <pubDate>Thu, 06 Sep 2018 00:00:00 +0000</pubDate>
      
      <guid>/center-of-gravity/</guid>
      <description>


&lt;p&gt;Drawing inspiration from FiveThirtyEight’s &lt;a href=&#34;https://fivethirtyeight.com/features/the-stanley-cup-center-of-gravity-is-somewhere-in-lake-huron/&#34;&gt;article&lt;/a&gt; locating the Stanley Cup’s center of gravity, or the average geographic point of all Stanley Cup winners, I wondered where other leagues (MLB, NBA, NFL) championship trophies’ geographical center could lie. Using Cartesian coordinates for each champion’s city, I mapped the location for each league. The corresponding code and plots are shown below.&lt;/p&gt;
&lt;hr /&gt;
&lt;div id=&#34;load-packages&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Load Packages&lt;/h3&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;library(rvest) 
library(tidyverse)
library(ggmap) 
library(DT)
library(leaflet) &lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div id=&#34;scrape-and-clean-data&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Scrape and Clean Data&lt;/h3&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;#scrape NFL table
nfl &amp;lt;- read_html(&amp;quot;http://www.espn.com/nfl/superbowl/history/winners&amp;quot;) %&amp;gt;%
  html_node(&amp;quot;table&amp;quot;) %&amp;gt;%
  html_table()

#remove top two header rows
nfl &amp;lt;- nfl[-c(1:2),]

#remove losing teams
nfl &amp;lt;- nfl %&amp;gt;%
  separate(X4, into = &amp;quot;Winner&amp;quot;, sep = &amp;quot;,&amp;quot;)

#remove winning team score
nfl$Winner &amp;lt;- gsub(&amp;#39;[[:digit:]]+&amp;#39;, &amp;#39;&amp;#39;, nfl[,&amp;quot;Winner&amp;quot;])

#create vector of team names in column
teams &amp;lt;- c(&amp;quot;Jets&amp;quot;, &amp;quot;Giants&amp;quot;, &amp;quot;Steelers&amp;quot;, &amp;quot;Saints&amp;quot;, &amp;quot;Packers&amp;quot;, &amp;quot;Ravens&amp;quot;, &amp;quot;Seahawks&amp;quot;, &amp;quot;Patriots&amp;quot;, &amp;quot;Broncos&amp;quot;, &amp;quot;Eagles&amp;quot;)

#remove team names from column and replace ambiguous city names
nfl$Winner &amp;lt;- gsub(paste0(teams,collapse = &amp;quot;|&amp;quot;),&amp;quot;&amp;quot;, nfl$Winner) %&amp;gt;%
  trimws(&amp;quot;right&amp;quot;) %&amp;gt;%
  recode(&amp;quot;New York&amp;quot; = &amp;quot;New York, NY&amp;quot;, &amp;quot;New England&amp;quot; = &amp;quot;Boston&amp;quot;, &amp;quot;Washington&amp;quot; = &amp;quot;Washington, D.C.&amp;quot;)

#optain latitude and longitude
nfl_locations &amp;lt;- geocode(nfl$Winner)
nfl &amp;lt;- bind_cols(nfl, nfl_locations)&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;#scrape NBA data
nba &amp;lt;- read_html(&amp;quot;https://simple.wikipedia.org/wiki/List_of_NBA_champions&amp;quot;) %&amp;gt;%
  html_node(&amp;quot;table&amp;quot;) %&amp;gt;%
  html_table()

#clean data
nba &amp;lt;- nba[,1:2] %&amp;gt;%
  rename(winner = `Winning team`) %&amp;gt;%
  separate(winner, into = &amp;quot;Winner&amp;quot;, sep = &amp;quot; &amp;quot;)

#replace ambiguous city names
nba$Winner &amp;lt;- recode(nba$Winner,&amp;quot;St.&amp;quot; = &amp;quot;St. Louis&amp;quot;, &amp;quot;New&amp;quot; = &amp;quot;New York, NY&amp;quot;, &amp;quot;Los&amp;quot; = &amp;quot;Los Angeles&amp;quot;,   &amp;quot;Golden&amp;quot; = &amp;quot;Oakland&amp;quot;, &amp;quot;San&amp;quot; = &amp;quot;San Antonio&amp;quot;, &amp;quot;Washington&amp;quot; = &amp;quot;Washington, D.C.&amp;quot;)

#optain latitude and longitude
nba_locations &amp;lt;- geocode(nba$Winner)
nba &amp;lt;- bind_cols(nba, nba_locations)&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;#scrape MLB data
mlb &amp;lt;- read_html(&amp;quot;http://www.espn.com/mlb/worldseries/history/winners&amp;quot;) %&amp;gt;%
  html_node(&amp;quot;table&amp;quot;) %&amp;gt;%
  html_table()

#remove, sort, and seperate rows
mlb &amp;lt;- mlb[-c(1:2),] %&amp;gt;%
  separate(X2, into = &amp;quot;Winner&amp;quot;, sep = &amp;quot; &amp;quot;) %&amp;gt;%
  arrange(-row_number())

#replace ambiguous city names
mlb$Winner &amp;lt;- recode(mlb$Winner, &amp;quot;St.&amp;quot; = &amp;quot;St. Louis&amp;quot;, &amp;quot;New&amp;quot; = &amp;quot;New York, NY&amp;quot;, &amp;quot;Brooklyn&amp;quot; = &amp;quot;New York, NY&amp;quot;, &amp;quot;Los&amp;quot; = &amp;quot;Los Angeles&amp;quot;, &amp;quot;Kansas&amp;quot; = &amp;quot;Kansas City&amp;quot;, &amp;quot;Florida&amp;quot; = &amp;quot;Miami&amp;quot;, &amp;quot;Washington&amp;quot; = &amp;quot;Washington, D.C.&amp;quot;, &amp;quot;Arizona&amp;quot; = &amp;quot;Phoenix&amp;quot;, &amp;quot;San&amp;quot; = &amp;quot;San Francisco&amp;quot;)

#optain latitude and longitude
mlb_locations &amp;lt;- geocode(mlb$Winner)
mlb &amp;lt;- bind_cols(mlb, mlb_locations)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div id=&#34;calculate-center-of-gravity&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Calculate Center of Gravity&lt;/h3&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;#create function to find average point
find_center &amp;lt;- function(df){
  
df2 &amp;lt;- df %&amp;gt;%
  mutate(rad_lon = df[,&amp;quot;lon&amp;quot;]*pi/180, rad_lat = df[,&amp;quot;lat&amp;quot;]*pi/180) %&amp;gt;% 
  mutate(X = cos(rad_lat) * cos(rad_lon)) %&amp;gt;%
  mutate(Y = cos(rad_lat) * sin(rad_lon)) %&amp;gt;%
  mutate(Z = sin(rad_lat)) %&amp;gt;%
  summarise(X = mean(X), Y = mean(Y), Z = mean(Z)) %&amp;gt;% #find mean
  mutate(Lon = atan2(Y,X), Hyp = sqrt(X*X+Y*Y), Lat = atan2(Z, Hyp)) %&amp;gt;%  
  select(Lon, Lat) %&amp;gt;%
  mutate(Lon = Lon*180/pi, Lat = Lat*180/pi)

return(df2)
}

#locate center of gravity for each league
nfl_center &amp;lt;- find_center(nfl)
nba_center &amp;lt;- find_center(nba)
mlb_center &amp;lt;- find_center(mlb)&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;#find center of gravity after each year
for (i in 1:nrow(nfl)) {
                    nfl$lon_center[i] &amp;lt;- find_center(nfl[1:i,])[[1]]
                    nfl$lat_center[i] &amp;lt;- find_center(nfl[1:i,])[[2]]
}


for (i in 1:nrow(nba)) {
                    nba$lon_center[i] &amp;lt;- find_center(nba[1:i,])[[1]]
                    nba$lat_center[i] &amp;lt;- find_center(nba[1:i,])[[2]]
  }

for (i in 1:nrow(mlb)) {
                    mlb$lon_center[i] &amp;lt;- find_center(mlb[1:i,])[[1]]
                    mlb$lat_center[i] &amp;lt;- find_center(mlb[1:i,])[[2]]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;/post/center-of-gravity_files/figure-html/unnamed-chunk-2-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;The NBA and MLB seem to be trending westward while the NFL looks to be boomeranging back east of the Mississippi. With the Yankees’ 27 championships (not to mention the NY Giants 5 titles plus the Mets 2 in addition to the Brooklyn Dodgers’ lone Series win) it’s no surprise that the MLB’s center of gravity is the furthest east. The Boston Celtic’s ’60s dynasty seems to have left its mark on the Larry O’Brien trophy, carrying the midpoint to upstate New York before ultimately trickling down through Illinois. Use the map below to toggle between leagues and a see which cities have won the most hardware.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;total-titles-by-city&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Total Titles by City&lt;/h3&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;nfl_total &amp;lt;- nfl %&amp;gt;%
  group_by(Winner) %&amp;gt;%
  select(Winner, lon, lat) %&amp;gt;%
  add_tally()

mlb_total &amp;lt;- mlb %&amp;gt;%
  group_by(Winner) %&amp;gt;%
  select(Winner, lon, lat) %&amp;gt;%
  add_tally()

nba_total &amp;lt;- nba %&amp;gt;%
  group_by(Winner) %&amp;gt;%
  select(Winner, lon, lat) %&amp;gt;%
  add_tally()&lt;/code&gt;&lt;/pre&gt;
&lt;iframe width=&#34;100%&#34; height=&#34;800&#34; frameborder=&#34;F&#34; src=&#34;https://chadbixby.shinyapps.io/Center-of-Gravity-App/&#34;&gt;
&lt;/iframe&gt;
&lt;div id=&#34;references&#34; class=&#34;section level4&#34;&gt;
&lt;h4&gt;References&lt;/h4&gt;
&lt;p&gt;D. Kahle and H. Wickham. ggmap: Spatial Visualization with ggplot2. The R
Journal, 5(1), 144-161. URL
&lt;a href=&#34;http://journal.r-project.org/archive/2013-1/kahle-wickham.pdf&#34; class=&#34;uri&#34;&gt;http://journal.r-project.org/archive/2013-1/kahle-wickham.pdf&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Spotify AnalYEsis</title>
      <link>/spotify-analyesis/</link>
      <pubDate>Thu, 30 Aug 2018 00:00:00 +0000</pubDate>
      
      <guid>/spotify-analyesis/</guid>
      <description>
&lt;script src=&#34;/rmarkdown-libs/kePrint/kePrint.js&#34;&gt;&lt;/script&gt;


&lt;p&gt;As the &lt;a href=&#34;https://en.wikipedia.org/wiki/Internet_of_things&#34;&gt;Internet of Things&lt;/a&gt; (IoT) landscape continues to grow, practically everyone and everything, it seems, is compiling data or at least generating statistics for any variable imaginable. And music is no exception. The music streaming service, Spotify, stores an array of features for each song in its library. They record characteristics such as acousticness, danceability, energy and more. With these variables in mind, I conducted some exploratory analysis along with a couple clustering methods on Kanye West’s &lt;em&gt;Spotify&lt;/em&gt; discography. The following report utilizes Spotify’s Web API through Charlie Thompson’s &lt;code&gt;spotifyr&lt;/code&gt; package which you can check out &lt;a href=&#34;http://www.rdocumentation.org/packages/spotifyr&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;div id=&#34;exploratory-data-analysis&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Exploratory Data Analysis&lt;/h2&gt;
&lt;div id=&#34;load-packages&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Load Packages&lt;/h3&gt;
&lt;p&gt;The following code and plots make use of these packages:&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;library(spotifyr)
library(tidyverse)
library(knitr)
library(kableExtra)
library(ggridges)
library(plotly)
library(scales)
library(ggfortify)
library(ggdendro)
library(dendextend)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div id=&#34;import-data&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Import Data&lt;/h3&gt;
&lt;p&gt;First let’s import the audio features for Kanye West and take a quick look at the data.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;kanye &amp;lt;- get_artist_audio_features(artist = &amp;quot;kanye west&amp;quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After viewing the data, I noticed a few tracks (rows) are duplicated since some albums contain edited, clean, and/or live versions. Those rows will be removed in addition to some irrelevant columns. Also let’s be sure we don’t have any missing values.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;kanye2 &amp;lt;- kanye %&amp;gt;%
  filter(!(album_name %in% c(&amp;quot;808s &amp;amp; Heartbreak (Softpak)&amp;quot;, &amp;quot;Late Orchestration&amp;quot;, 
                             &amp;quot;The College Dropout (Edited)&amp;quot;, 
                             &amp;quot;Graduation (Alternative Business Partners)&amp;quot;))) %&amp;gt;%
    select(-c(artist_uri, album_uri, album_type, is_collaboration, track_uri,
            track_preview_url, album_release_year, artist_name, album_img, 
            album_release_date, track_open_spotify_url, track_number,
            disc_number, key, mode, key_mode, album_popularity, time_signature))

sum(is.na(kanye2))&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## [1] 0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The dataset we will be working with now has 125 rows and 13 columns with no missing observations!&lt;/p&gt;
&lt;p&gt;###Danceability
Spotify defines danceability as&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“How suitable a track is for dancing based on a combination of musical elements including tempo,
rhythm stability, beat strength, and overall regularity. A value of 0.0 is least danceable and
1.0 is most danceable.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Before determining which album Spotify deems the most danceable, let’s take a look at how danceability is distributed on each album.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/post/spotify_files/figure-html/unnamed-chunk-3-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;The dashed vertical line in the middle represents the midpoint on the danceability scale. Also, the smaller tick marks at the bottom of each shape represent one song on an album. Each album appears to be more danceable than not, but let’s weight each song by its duration to get a better picture of each album in its entirety. The following graph outlines the results.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;kanye_dance &amp;lt;- kanye2 %&amp;gt;%
  mutate(total_dance = danceability*duration_ms) %&amp;gt;%
  group_by(album_name) %&amp;gt;%
  summarise(avg_danceability = sum(total_dance)/length(album_name)/10000)&lt;/code&gt;&lt;/pre&gt;
&lt;iframe width=&#34;800&#34; height=&#34;500&#34; frameborder=&#34;0&#34; scrolling=&#34;no&#34; src=&#34;//plot.ly/~bixby96/5.embed?link=false&amp;amp;logo=false&#34;&gt;
&lt;/iframe&gt;
&lt;p&gt;Overall, &lt;em&gt;My Beautiful Dark Twisted Fantasy&lt;/em&gt; and &lt;em&gt;808s &amp;amp; Heartbreak&lt;/em&gt; represent Kanye’s most danceable albums. The following table lists his top 10 most danceable songs.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;kanye_dance_songs &amp;lt;- kanye2 %&amp;gt;%
  arrange(desc(danceability)) %&amp;gt;%
  select(album_name, track_name, danceability)

kable(head(kanye_dance_songs, 10)) %&amp;gt;%
    kable_styling(full_width = F)&lt;/code&gt;&lt;/pre&gt;
&lt;table class=&#34;table&#34; style=&#34;width: auto !important; margin-left: auto; margin-right: auto;&#34;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&#34;text-align:left;&#34;&gt;
album_name
&lt;/th&gt;
&lt;th style=&#34;text-align:left;&#34;&gt;
track_name
&lt;/th&gt;
&lt;th style=&#34;text-align:right;&#34;&gt;
danceability
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
ye
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
All Mine
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
0.925
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Late Registration
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Gone
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
0.851
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
KIDS SEE GHOSTS
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Kids See Ghosts
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
0.841
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
The Life Of Pablo
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Feedback
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
0.837
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
The Life Of Pablo
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
30 Hours
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
0.822
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
808s &amp;amp; Heartbreak
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Paranoid
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
0.812
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
808s &amp;amp; Heartbreak
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Heartless
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
0.789
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Yeezus
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Black Skinhead
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
0.775
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
The Life Of Pablo
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Facts (Charlie Heat Version)
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
0.769
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
KIDS SEE GHOSTS
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
4th Dimension
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
0.765
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div id=&#34;valence&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Valence&lt;/h3&gt;
&lt;p&gt;Spotify defines Valence as&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“A measure from 0.0 to 1.0 describing the musical positiveness conveyed by a
track. Tracks with high valence sound more positive (e.g. happy, cheerful,
euphoric), while tracks with low valence sound more negative (e.g. sad, depressed, angry)”&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Again, let’s look at the overall distribution for each album, but for valence this time.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;/post/spotify_files/figure-html/unnamed-chunk-7-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Perhaps a bit more polarizing than the danceability metric, most albums seem to have their fair share of both positive and negative sounding songs. Now weighting valence by song duration, let’s discover Kanye’s happiest (and saddest) album.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;kanye_val &amp;lt;- kanye2 %&amp;gt;%
  mutate(total_valence = valence*duration_ms) %&amp;gt;%
  group_by(album_name) %&amp;gt;%
  summarise(avg_valence = sum(total_valence/length(album_name)/10000))&lt;/code&gt;&lt;/pre&gt;
&lt;iframe width=&#34;800&#34; height=&#34;500&#34; frameborder=&#34;0&#34; scrolling=&#34;no&#34; src=&#34;//plot.ly/~bixby96/3.embed?link=false&amp;amp;logo=false&#34;&gt;
&lt;/iframe&gt;
&lt;p&gt;With a valence score of 14.68, the happiest Kanye release came way back in 2004 with his debut hit &lt;em&gt;The College Dropout&lt;/em&gt;. Interestingly, the four albums with the lowest valence score also make up his most recent work. The tracks with the lowest valence scores are shown below.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;kanye_valence_songs &amp;lt;- kanye2 %&amp;gt;%
  select(album_name, track_name, valence) %&amp;gt;%
  arrange(valence)

kable(head(kanye_valence_songs,10)) %&amp;gt;%
    kable_styling(full_width = F)&lt;/code&gt;&lt;/pre&gt;
&lt;table class=&#34;table&#34; style=&#34;width: auto !important; margin-left: auto; margin-right: auto;&#34;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&#34;text-align:left;&#34;&gt;
album_name
&lt;/th&gt;
&lt;th style=&#34;text-align:left;&#34;&gt;
track_name
&lt;/th&gt;
&lt;th style=&#34;text-align:right;&#34;&gt;
valence
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
The Life Of Pablo
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Frank’s Track
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
0.0000
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Yeezus
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Hold My Liquor
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
0.0399
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
ye
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Violent Crimes
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
0.0400
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
The Life Of Pablo
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Waves
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
0.0565
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
808s &amp;amp; Heartbreak
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Welcome To Heartbreak
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
0.0734
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Graduation
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Can’t Tell Me Nothing
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
0.0963
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
My Beautiful Dark Twisted Fantasy
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Monster
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
0.0964
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Graduation
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
I Wonder
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
0.1060
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
My Beautiful Dark Twisted Fantasy
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Runaway
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
0.1090
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
The Life Of Pablo
&lt;/td&gt;
&lt;td style=&#34;text-align:left;&#34;&gt;
Wolves
&lt;/td&gt;
&lt;td style=&#34;text-align:right;&#34;&gt;
0.1180
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div id=&#34;other-variables&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Other Variables&lt;/h3&gt;
&lt;p&gt;Interested in exploring the rest of the variables? Choose which characteristics to plot and select which albums to compare using the interactive graph
below!&lt;/p&gt;
&lt;iframe width=&#34;800&#34; height=&#34;700&#34; frameborder=&#34;F&#34; src=&#34;https://chadbixby.shinyapps.io/kanye-app/&#34;&gt;
&lt;/iframe&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;clustering&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Clustering&lt;/h2&gt;
&lt;div id=&#34;hierarchical-clustering&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Hierarchical Clustering&lt;/h3&gt;
&lt;p&gt;Now on to some clustering methods. Let’s determine which albums sound the most alike using hierarchical clustering. A tree with a height of 4 and complete linkage is shown below.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;kanye3 &amp;lt;- kanye2 %&amp;gt;%
  select(-c(track_name, track_popularity)) %&amp;gt;%
  group_by(album_name) %&amp;gt;%
  summarise(dance = sum(danceability*duration_ms)/length(album_name),
            energy = sum(energy*duration_ms)/length(album_name),
            loudness = sum(loudness*duration_ms)/length(album_name),
            speechiness = sum(speechiness*duration_ms)/length(album_name),
            acousticness = sum(acousticness*duration_ms)/length(album_name),
            instrumentalness = sum(instrumentalness*duration_ms)/length(album_name),
            liveness = sum(liveness*duration_ms)/length(album_name),
            valence = sum(valence*duration_ms)/length(album_name),
            tempo = sum(tempo*duration_ms)/length(album_name)) %&amp;gt;%
  remove_rownames() %&amp;gt;%
  column_to_rownames(&amp;quot;album_name&amp;quot;)

kanye.hc &amp;lt;- hclust(dist(scale(kanye3)), method = &amp;quot;complete&amp;quot;)
kanye.tree &amp;lt;- dendro_data(kanye.hc, type = &amp;quot;rectangle&amp;quot;)
kanye.hc.4 &amp;lt;- cutree(kanye.hc, k = 4)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;/post/spotify_files/figure-html/unnamed-chunk-12-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Kanye’s first three releases belong to one cluster while his last four belong to another. The middle releases, &lt;em&gt;808s &amp;amp; Heartbreak&lt;/em&gt; and &lt;em&gt;Twisted Fantasy&lt;/em&gt;, are not only his most danceable records but his most unique sounding as well; they each populate their own cluster.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;principle-component-analysis&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Principle Component Analysis&lt;/h3&gt;
&lt;p&gt;Now let’s use those variables and see if we can discover if his more popular songs score similarly for each variable. Using a PCA to reduce dimensionality and account for correlation we can try to reveal any patterns.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;kanye_pca &amp;lt;- prcomp(kanye2[,3:11], center = T, scale = T)
summary(kanye_pca)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## Importance of components:
##                           PC1    PC2    PC3    PC4    PC5     PC6     PC7
## Standard deviation     1.5958 1.2793 1.0779 0.9988 0.9512 0.84785 0.69853
## Proportion of Variance 0.2829 0.1819 0.1291 0.1108 0.1005 0.07987 0.05422
## Cumulative Proportion  0.2829 0.4648 0.5939 0.7047 0.8053 0.88513 0.93934
##                            PC8     PC9
## Standard deviation     0.62701 0.39085
## Proportion of Variance 0.04368 0.01697
## Cumulative Proportion  0.98303 1.00000&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Using two principle components we can describe a little over 46% of the variability in the data (shown in the plot below). To explain at least 90% of the variability, we need to use 7 principle components. The following graph shows the top two principle components with the top quartile of his most popular songs mapped to one color and the rest to another.&lt;/p&gt;
&lt;iframe width=&#34;800&#34; height=&#34;600&#34; frameborder=&#34;0&#34; scrolling=&#34;no&#34; src=&#34;//plot.ly/~bixby96/1.embed?link=false&amp;amp;logo=false&#34;&gt;
&lt;/iframe&gt;
&lt;p&gt;The most popular songs don’t appear to belong to any specific area or cluster on the graph, but it does look like &lt;code&gt;Energy&lt;/code&gt; and &lt;code&gt;Loudness&lt;/code&gt; are correlated. Try graphing them using the interactive plot above!&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>About</title>
      <link>/page/about/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/page/about/</guid>
      <description>


&lt;div id=&#34;purpose&#34; class=&#34;section level3&#34;&gt;
&lt;h3&gt;Purpose&lt;/h3&gt;
&lt;p&gt;The purpose of creating this website was to generate a space to not only share my independent analytical work but to also serve as a portfolio of sorts. Each post will center around dissecting a dataset and revealing any underlying information. I’ll try to keep it fresh and analyze a variety of topics, but ultimately, I’ll explore whatever I find most interesting (so expect a few sports-related posts). My goal is to publish at least a couple of times a month so feel free to contact me about anything! (suggestions, what you liked, didn’t like, etc.)&lt;/p&gt;
&lt;center&gt;
A Proud Contributer to &lt;a href=&#34;http://www.R-bloggers.com&#34;&gt;R-Bloggers&lt;/a&gt; and &lt;a href=&#34;https://rweekly.org&#34;&gt;R Weekly&lt;/a&gt;
&lt;/center&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Contact</title>
      <link>/contact/contact/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/contact/contact/</guid>
      <description>


&lt;center&gt;
&lt;strong&gt;Have a question or suggestion? Fill out the form below!&lt;/strong&gt;
&lt;/center&gt;
&lt;br&gt;
&lt;form class=&#34;form&#34; id=&#34;contactform&#34; action=&#34;//formspree.io/chadbixby15@gmail.com&#34; method=&#34;POST&#34;&gt;
&lt;fieldset class=&#34;field&#34;&gt;
&lt;label class=&#34;label&#34; for=&#34;name&#34;&gt;&lt;span class=&#34;label-content&#34;&gt;Enter Your Name:&lt;/span&gt;&lt;/label&gt;&lt;br&gt;
&lt;input class=&#34;input&#34; type=&#34;text&#34; size = &#34;30&#34; name=&#34;name&#34; placeholder=&#34;Dwight K. Schrute&#34; id=&#34;name&#34; required&gt;&lt;br&gt;&lt;br&gt;
&lt;label class=&#34;label&#34; for=&#34;_replyto&#34;&gt;&lt;span class=&#34;label-content&#34;&gt;Email Address: &lt;/span&gt;&lt;/label&gt;&lt;br&gt;
&lt;input class=&#34;input&#34; type=&#34;email&#34; size = &#34;30&#34; name=&#34;_replyto&#34; placeholder=&#34;dwight@beetfarms.com&#34; id=&#34;_replyto&#34; required&gt;&lt;br&gt;&lt;br&gt;
&lt;label class=&#34;label&#34; for=&#34;message&#34;&gt;&lt;span class=&#34;label-content&#34;&gt;Your message:&lt;/span&gt;&lt;/label&gt;&lt;br&gt;
&lt;textarea class=&#34;input&#34; name=&#34;message&#34; rows=&#34;4&#34; cols=&#34;100%&#34; placeholder=&#34;Message&#34; id=&#34;message&#34; required&gt;
&lt;/textarea&gt;
&lt;br&gt;
&lt;input class=&#34;hidden&#34; type=&#34;text&#34; name=&#34;_gotcha&#34; style=&#34;display:none&#34;&gt;
&lt;input class=&#34;hidden&#34; type=&#34;hidden&#34; name=&#34;_subject&#34; value=&#34;Website Message&#34;&gt;
&lt;input class=&#34;button submit&#34; type=&#34;submit&#34; value=&#34;Send&#34;&gt;
&lt;input type=&#34;hidden&#34; name=&#34;_next&#34; value=&#34;/page/thanks&#34; /&gt;
&lt;/fieldset&gt;
&lt;/form&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Thank You</title>
      <link>/page/thanks/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/page/thanks/</guid>
      <description>


&lt;p&gt;&lt;img src=&#34;/page/thanks_files/light-sign-typography-lighting.jpg&#34; /&gt;&lt;/p&gt;
&lt;center&gt;
#I will get back to you soon!
&lt;/center&gt;
</description>
    </item>
    
  </channel>
</rss>