<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/slopegraphs-and-r-a-pleasant-diversion-may-26-2018/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://ibecav.github.io/slopegraph/"> Chuck Powell</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>I try to at least scan the <a rel="nofollow" href="https://www.r-bloggers.com/" target="_blank">R-bloggers</a><br>
feed everyday. Not every article is of interest to me, but I often have<br>
one of two different reactions to at least one article. Sometimes it is<br>
an <em>“ah ha”</em> moment because the article is right on point for a problem<br>
I have now or have had in the past and the article provides a (better)<br>
solution. Other times my reaction is more of an <em>“oh yeah”</em>, because it<br>
is something I have been meaning to investigate, or something I once<br>
knew, but the article brings a different perspective to it.</p>
<p>The second case happened to me this week. I’ve been aware of slopegraphs<br>
and bumpcharts for quite some time, and I certainly am aware of <a rel="nofollow" href="https://www.edwardtufte.com/tufte/" target="_blank">Tufte’s<br>
work</a>. As an amateur military<br>
historian I’ve always loved, for example, <a rel="nofollow" href="https://www.edwardtufte.com/tufte/posters" target="_blank">his<br>
poster</a> depicting Napoleon’s<br>
Russian Campaign. So when I saw the article from <a rel="nofollow" href="https://www.r-bloggers.com/author/murtaza-haider/" target="_blank">Murtaza<br>
Haider</a> titled<br>
<em>“Edward Tufte’s Slopegraphs and political fortunes in Ontario”</em> I<br>
just had to take a peek and revisit the topic.</p>
<p>The article does a good job of looking at slopegraphs in both <code>R</code> (via<br>
<code>plotrix</code>) and <code>Stata</code>, even providing the code to do the work. My<br>
challenge was that even though I’m adequate at plotting in base R, I<br>
much prefer using <code>ggplot2</code> wherever and whenever possible. My memory<br>
was that I had seen another article on the related topic of a<br>
<code>bumpchart</code> on R-bloggers in the not too distant past. A little<br>
sleuthing turned up <a rel="nofollow" href="https://dominikkoch.github.io/Bump-Chart/" target="_blank">this earlier<br>
article</a> from <a rel="nofollow" href="https://dominikkoch.github.io/aboutme/" target="_blank">Dominik<br>
Koch</a> who wrote some code to<br>
compare national performance at the Winter Olympics, <em>“Bump Chart –<br>
Track performance over time”</em>.</p>
<p>Finally, I wound up at <a rel="nofollow" href="https://github.com/leeper/slopegraph" target="_blank">this Github<br>
repository</a> for a project called<br>
<em>“Edward Tufte-Inspired Slopegraphs”</em> from <a rel="nofollow" href="https://github.com/leeper" target="_blank">Thomas J.<br>
Leeper</a> who has been building code to make<br>
slopegraphs using both base plotting functions and <code>ggplot2</code>.</p>
<p>My post today will draw a little bit from all their work and hopefully<br>
provide some useful samples for others to draw on if they share some of<br>
my quirks about data layout and a preference for <code>ggplot2</code> versus base<br>
<code>plot</code>. I’m going to focus almost exclusively on slopegraphs, although<br>
much of the work could be extended to bumpcharts as well.</p>
<h2>Setup and library loading</h2>
<p>We’re going to make occasional use of <code>dplyr</code> to manipulate the data,<br>
extensive use of <code>ggplot2</code> to do the plotting and <code>ggrepel</code> to solve one<br>
specific labeling problem. We’ll load them and I am suppressing the<br>
message from <code>dplyr</code> about namespace overrides.</p>
<div>
<div>
<pre><code><span>require</span><span>(</span><span>dplyr</span><span>)</span><span>
</span><span>require</span><span>(</span><span>ggplot2</span><span>)</span><span>
</span><span>require</span><span>(</span><span>ggrepel</span><span>)</span><span>
</span><span>require</span><span>(</span><span>kableExtra</span><span>)</span><span>
</span></code></pre>
</div>
</div>
<h2>Politics in Ontario</h2>
<p><a rel="nofollow" href="https://ekonometrics.blogspot.com/2018/05/edward-tuftes-slopegraphs-and-political.html" target="_blank">The original<br>
post</a><br>
is about plotting the data from some polling results in Ontario. For the<br>
reader’s convenience I’ve made the data available via a <code>structure</code><br>
command. We have data about two different polling dates, for 5 political<br>
parties, and the measured variable is percent of people supporting<br>
expressed as x.x (i.e. already multiplied by<br>
100).</p>
<div>
<div>
<pre><code><span>data</span><span> </span><span>&lt;-</span><span> </span><span>structure</span><span>(</span><span>list</span><span>(</span><span> </span><span>Date</span><span> </span><span>=</span><span> </span><span>structure</span><span>(</span><span>c</span><span>(</span><span>1L</span><span>,</span><span> </span><span>1L</span><span>,</span><span> </span><span>1L</span><span>,</span><span> </span><span>1L</span><span>,</span><span> </span><span>1L</span><span>,</span><span> </span><span>2L</span><span>,</span><span> </span><span>2L</span><span>,</span><span> </span><span>2L</span><span>,</span><span> </span><span>2L</span><span>,</span><span> </span><span>2L</span><span>),</span><span> </span><span>.Label</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>&quot;11-May-18&quot;</span><span>,</span><span> </span><span>&quot;18-May-18&quot;</span><span>),</span><span> </span><span>class</span><span> </span><span>=</span><span> </span><span>&quot;factor&quot;</span><span>),</span><span> </span><span>Party</span><span> </span><span>=</span><span> </span><span>structure</span><span>(</span><span>c</span><span>(</span><span>5L</span><span>,</span><span> </span><span>3L</span><span>,</span><span> </span><span>2L</span><span>,</span><span> </span><span>1L</span><span>,</span><span> </span><span>4L</span><span>,</span><span> </span><span>5L</span><span>,</span><span> </span><span>3L</span><span>,</span><span> </span><span>2L</span><span>,</span><span> </span><span>1L</span><span>,</span><span> </span><span>4L</span><span>),</span><span> </span><span>.Label</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>&quot;Green&quot;</span><span>,</span><span> </span><span>&quot;Liberal&quot;</span><span>,</span><span> </span><span>&quot;NDP&quot;</span><span>,</span><span> </span><span>&quot;Others&quot;</span><span>,</span><span> </span><span>&quot;PC&quot;</span><span>),</span><span> </span><span>class</span><span> </span><span>=</span><span> </span><span>&quot;factor&quot;</span><span>),</span><span> </span><span>Pct</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>42.3</span><span>,</span><span> </span><span>28.4</span><span>,</span><span> </span><span>22.1</span><span>,</span><span> </span><span>5.4</span><span>,</span><span> </span><span>1.8</span><span>,</span><span> </span><span>41.9</span><span>,</span><span> </span><span>29.3</span><span>,</span><span> </span><span>22.3</span><span>,</span><span> </span><span>5</span><span>,</span><span> </span><span>1.4</span><span>)),</span><span> </span><span>class</span><span> </span><span>=</span><span> </span><span>&quot;data.frame&quot;</span><span>,</span><span> </span><span>row.names</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>NA</span><span>,</span><span> </span><span>-10L</span><span>))</span><span>
</span><span>str</span><span>(</span><span>data</span><span>)</span><span>
</span></code></pre>
</div>
</div>
<div>
<div>
<pre><code>## 'data.frame':    10 obs. of  3 variables:
##  $ Date : Factor w/ 2 levels &quot;11-May-18&quot;,&quot;18-May-18&quot;: 1 1 1 1 1 2 2 2 2 2
##  $ Party: Factor w/ 5 levels &quot;Green&quot;,&quot;Liberal&quot;,..: 5 3 2 1 4 5 3 2 1 4
##  $ Pct  : num  42.3 28.4 22.1 5.4 1.8 41.9 29.3 22.3 5 1.4
</code></pre>
</div>
</div>
<div>
<div>
<pre><code><span>head</span><span>(</span><span>data</span><span>)</span><span>
</span></code></pre>
</div>
</div>
<div>
<div>
<pre><code>##        Date   Party  Pct
## 1 11-May-18      PC 42.3
## 2 11-May-18     NDP 28.4
## 3 11-May-18 Liberal 22.1
## 4 11-May-18   Green  5.4
## 5 11-May-18  Others  1.8
## 6 18-May-18      PC 41.9
</code></pre>
</div>
</div>
<p>Let’s just take the data as we have it and feed it to <code>ggplot</code> in a nice<br>
simple fashion and see what we get with very little effort.</p>
<div>
<div>
<pre><code><span>ggplot</span><span>(</span><span>data</span><span> </span><span>=</span><span> </span><span>data</span><span>,</span><span> </span><span>aes</span><span>(</span><span>x</span><span> </span><span>=</span><span> </span><span>Date</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>Pct</span><span>,</span><span> </span><span>group</span><span> </span><span>=</span><span> </span><span>Party</span><span>))</span><span> </span><span>+</span><span>
</span><span>geom_line</span><span>(</span><span>aes</span><span>(</span><span>color</span><span> </span><span>=</span><span> </span><span>Party</span><span>,</span><span> </span><span>alpha</span><span> </span><span>=</span><span> </span><span>1</span><span>),</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>2</span><span>)</span><span> </span><span>+</span><span>
</span><span>geom_point</span><span>(</span><span>aes</span><span>(</span><span>color</span><span> </span><span>=</span><span> </span><span>Party</span><span>,</span><span> </span><span>alpha</span><span> </span><span>=</span><span> </span><span>1</span><span>),</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>4</span><span>)</span><span> </span><span>+</span><span>
</span><span># Labelling as desired</span><span>
</span><span>labs</span><span>(</span><span>
</span><span>title</span><span> </span><span>=</span><span> </span><span>&quot;Voter's stated preferences for June 7 elections in Ontario&quot;</span><span>,</span><span>
</span><span>subtitle</span><span> </span><span>=</span><span> </span><span>&quot;(Mainstreet Research)&quot;</span><span>,</span><span>
</span><span>caption</span><span> </span><span>=</span><span> </span><span>&quot;https://www.mainstreetresearch.ca/gap-between-ndp-and-pcs-narrows-while-liberals-hold-steady/&quot;</span><span>
</span><span>)</span><span>
</span></code></pre>
</div>
</div>
<p><img alt="" src="https://i0.wp.com/ibecav.github.io/images/slopegraph1a-1.png?w=456" data-recalc-dims="1"></p>
<p>The nice thing about <code>ggplot</code> is once you get used to the syntax it<br>
becomes very “readable”. We’ve identified our dataset, the x &amp; y<br>
variables and our grouping variable. Lines too big? An adjustment to<br>
<code>size = 2</code> does it. Don’t like colors? Pull the <code>color = Party</code> clause.</p>
<p>So we’re already pretty close to what we need. Things are scaled<br>
properly and the basic labeling of titles etc. is accomplished. Our<br>
biggest “problem” is that <code>ggplot</code> has been a little too helpful and<br>
adding some things we’d like to remove to give it a more <em>“Tuftesque”</em><br>
look. So what we’ll do in the next few steps is add lines of code – but<br>
they are mainly designed to remove unwanted elements. This is in<br>
contrast to a base plot where we have to write the code to add elements.</p>
<p>So lets:</p>
<ul>
<li>Move the x axis labels to the top with <code>scale_x_discrete(position =<br>
&quot;top&quot;)</code></li>
<li>Change to a nice clean black and white theme <code>theme_bw()</code></li>
<li>Not display any legend(s) <code>theme(legend.position = &quot;none&quot;)</code></li>
<li>Remove the default border from our plot <code>theme(panel.border =<br>
element_blank())</code></li>
</ul>
<p></p>
<div>
<div>
<pre><code><span>ggplot</span><span>(</span><span>data</span><span> </span><span>=</span><span> </span><span>data</span><span>,</span><span> </span><span>aes</span><span>(</span><span>x</span><span> </span><span>=</span><span> </span><span>Date</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>Pct</span><span>,</span><span> </span><span>group</span><span> </span><span>=</span><span> </span><span>Party</span><span>))</span><span> </span><span>+</span><span>
</span><span>geom_line</span><span>(</span><span>aes</span><span>(</span><span>color</span><span> </span><span>=</span><span> </span><span>Party</span><span>,</span><span> </span><span>alpha</span><span> </span><span>=</span><span> </span><span>1</span><span>),</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>2</span><span>)</span><span> </span><span>+</span><span>
</span><span>geom_point</span><span>(</span><span>aes</span><span>(</span><span>color</span><span> </span><span>=</span><span> </span><span>Party</span><span>,</span><span> </span><span>alpha</span><span> </span><span>=</span><span> </span><span>1</span><span>),</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>4</span><span>)</span><span> </span><span>+</span><span>
</span><span># move the x axis labels up top</span><span>
</span><span>scale_x_discrete</span><span>(</span><span>position</span><span> </span><span>=</span><span> </span><span>&quot;top&quot;</span><span>)</span><span> </span><span>+</span><span>
</span><span>theme_bw</span><span>()</span><span> </span><span>+</span><span>
</span><span># Format tweaks</span><span>
</span><span># Remove the legend</span><span>
</span><span>theme</span><span>(</span><span>legend.position</span><span> </span><span>=</span><span> </span><span>&quot;none&quot;</span><span>)</span><span> </span><span>+</span><span>
</span><span># Remove the panel border</span><span>
</span><span>theme</span><span>(</span><span>panel.border</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span># Labelling as desired</span><span>
</span><span>labs</span><span>(</span><span>
</span><span>title</span><span> </span><span>=</span><span> </span><span>&quot;Voter's stated preferences for June 7 elections in Ontario&quot;</span><span>,</span><span>
</span><span>subtitle</span><span> </span><span>=</span><span> </span><span>&quot;(Mainstreet Research)&quot;</span><span>,</span><span>
</span><span>caption</span><span> </span><span>=</span><span> </span><span>&quot;https://www.mainstreetresearch.ca/gap-between-ndp-and-pcs-narrows-while-liberals-hold-steady/&quot;</span><span>
</span><span>)</span><span>
</span></code></pre>
</div>
</div>
<p><img alt="" src="https://i0.wp.com/ibecav.github.io/images/slopegraph1b-1.png?w=456" data-recalc-dims="1"></p>
<p>Nice progress! Continuing to remove things that can be considered<br>
“clutter” we add some additional lines that all end in<br>
<code>element_blank()</code> and are invoked to remove default plot items such as<br>
the plot grid, the y axcis text, etc..</p>
<div>
<div>
<pre><code><span>ggplot</span><span>(</span><span>data</span><span> </span><span>=</span><span> </span><span>data</span><span>,</span><span> </span><span>aes</span><span>(</span><span>x</span><span> </span><span>=</span><span> </span><span>Date</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>Pct</span><span>,</span><span> </span><span>group</span><span> </span><span>=</span><span> </span><span>Party</span><span>))</span><span> </span><span>+</span><span>
</span><span>geom_line</span><span>(</span><span>aes</span><span>(</span><span>color</span><span> </span><span>=</span><span> </span><span>Party</span><span>,</span><span> </span><span>alpha</span><span> </span><span>=</span><span> </span><span>1</span><span>),</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>2</span><span>)</span><span> </span><span>+</span><span>
</span><span>geom_point</span><span>(</span><span>aes</span><span>(</span><span>color</span><span> </span><span>=</span><span> </span><span>Party</span><span>,</span><span> </span><span>alpha</span><span> </span><span>=</span><span> </span><span>1</span><span>),</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>4</span><span>)</span><span> </span><span>+</span><span>
</span><span># move the x axis labels up top</span><span>
</span><span>scale_x_discrete</span><span>(</span><span>position</span><span> </span><span>=</span><span> </span><span>&quot;top&quot;</span><span>)</span><span> </span><span>+</span><span>
</span><span>theme_bw</span><span>()</span><span> </span><span>+</span><span>
</span><span># Format tweaks</span><span>
</span><span># Remove the legend</span><span>
</span><span>theme</span><span>(</span><span>legend.position</span><span> </span><span>=</span><span> </span><span>&quot;none&quot;</span><span>)</span><span> </span><span>+</span><span>
</span><span># Remove the panel border</span><span>
</span><span>theme</span><span>(</span><span>panel.border</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span># Remove just about everything from the y axis</span><span>
</span><span>theme</span><span>(</span><span>axis.title.y</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span>theme</span><span>(</span><span>axis.text.y</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span>theme</span><span>(</span><span>panel.grid.major.y</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span>theme</span><span>(</span><span>panel.grid.minor.y</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span># Remove a few things from the x axis and increase font size</span><span>
</span><span>theme</span><span>(</span><span>axis.title.x</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span>theme</span><span>(</span><span>panel.grid.major.x</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span>theme</span><span>(</span><span>axis.text.x.top</span><span> </span><span>=</span><span> </span><span>element_text</span><span>(</span><span>size</span><span>=</span><span>12</span><span>))</span><span> </span><span>+</span><span>
</span><span># Remove x &amp; y tick marks</span><span>
</span><span>theme</span><span>(</span><span>axis.ticks</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span># Labelling as desired</span><span>
</span><span>labs</span><span>(</span><span>
</span><span>title</span><span> </span><span>=</span><span> </span><span>&quot;Voter's stated preferences for June 7 elections in Ontario&quot;</span><span>,</span><span>
</span><span>subtitle</span><span> </span><span>=</span><span> </span><span>&quot;(Mainstreet Research)&quot;</span><span>,</span><span>
</span><span>caption</span><span> </span><span>=</span><span> </span><span>&quot;https://www.mainstreetresearch.ca/gap-between-ndp-and-pcs-narrows-while-liberals-hold-steady/&quot;</span><span>
</span><span>)</span><span>
</span></code></pre>
</div>
</div>
<p><img alt="" src="https://i2.wp.com/ibecav.github.io/images/slopegraph1c-1.png?w=456" data-recalc-dims="1"></p>
<p>Very nice! We’re almost there! The “almost” is because now that we<br>
have removed both the legend and all scales and tick marks we no longer<br>
know who is who, and what the numbers are! Plus, I’m a little unhappy<br>
with the way the titles are formatted, so we’ll play with that. Later,<br>
I’ll get fancy but for now let’s just add some simple text labels on<br>
the left and right to show the party name and their percentage. The code<br>
<code>geom_text(aes(label = Party))</code> will place the party name right on top<br>
of the points that anchor either end of the line. If we make that<br>
<code>geom_text(aes(label = paste0(Party, &quot; - &quot;, Pct, &quot;%&quot;)))</code> then we’ll get<br>
labels that have both the party and the percent all neatly formatted,<br>
but still right on top of the points that anchor the ends of the line.<br>
<code>hjust</code> controls horizontal justification so if we change it to<br>
<code>geom_text(aes(label = paste0(Party, &quot; - &quot;, Pct, &quot;%&quot;)), hjust = 1.35)</code><br>
both sets of labels will slide to the left which is exactly what we want<br>
for the May 11 labels but not the May 18 labels. If we feed <code>hjust</code> a<br>
negative number they’ll go the other way. So what we’ll do is filter the<br>
data using the <code>filter</code> function from <code>dplyr</code> and place the left hand<br>
labels differently than the right hand labels. While we’re at it we’ll<br>
make it bold face font and a little larger…</p>
<div>
<div>
<pre><code><span>ggplot</span><span>(</span><span>data</span><span> </span><span>=</span><span> </span><span>data</span><span>,</span><span> </span><span>aes</span><span>(</span><span>x</span><span> </span><span>=</span><span> </span><span>Date</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>Pct</span><span>,</span><span> </span><span>group</span><span> </span><span>=</span><span> </span><span>Party</span><span>))</span><span> </span><span>+</span><span>
</span><span>geom_line</span><span>(</span><span>aes</span><span>(</span><span>color</span><span> </span><span>=</span><span> </span><span>Party</span><span>,</span><span> </span><span>alpha</span><span> </span><span>=</span><span> </span><span>1</span><span>),</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>2</span><span>)</span><span> </span><span>+</span><span>
</span><span>geom_point</span><span>(</span><span>aes</span><span>(</span><span>color</span><span> </span><span>=</span><span> </span><span>Party</span><span>,</span><span> </span><span>alpha</span><span> </span><span>=</span><span> </span><span>1</span><span>),</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>4</span><span>)</span><span> </span><span>+</span><span>
</span><span>geom_text</span><span>(</span><span>data</span><span> </span><span>=</span><span> </span><span>data</span><span> </span><span>%>%</span><span> </span><span>filter</span><span>(</span><span>Date</span><span> </span><span>==</span><span> </span><span>&quot;11-May-18&quot;</span><span>),</span><span> </span><span>aes</span><span>(</span><span>label</span><span> </span><span>=</span><span> </span><span>paste0</span><span>(</span><span>Party</span><span>,</span><span> </span><span>&quot; - &quot;</span><span>,</span><span> </span><span>Pct</span><span>,</span><span> </span><span>&quot;%&quot;</span><span>))</span><span> </span><span>,</span><span> </span><span>hjust</span><span> </span><span>=</span><span> </span><span>1.35</span><span>,</span><span> </span><span>fontface</span><span> </span><span>=</span><span> </span><span>&quot;bold&quot;</span><span>,</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>4</span><span>)</span><span> </span><span>+</span><span>
</span><span>geom_text</span><span>(</span><span>data</span><span> </span><span>=</span><span> </span><span>data</span><span> </span><span>%>%</span><span> </span><span>filter</span><span>(</span><span>Date</span><span> </span><span>==</span><span> </span><span>&quot;18-May-18&quot;</span><span>),</span><span> </span><span>aes</span><span>(</span><span>label</span><span> </span><span>=</span><span> </span><span>paste0</span><span>(</span><span>Party</span><span>,</span><span> </span><span>&quot; - &quot;</span><span>,</span><span> </span><span>Pct</span><span>,</span><span> </span><span>&quot;%&quot;</span><span>))</span><span> </span><span>,</span><span> </span><span>hjust</span><span> </span><span>=</span><span> </span><span>-.35</span><span>,</span><span> </span><span>fontface</span><span> </span><span>=</span><span> </span><span>&quot;bold&quot;</span><span>,</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>4</span><span>)</span><span> </span><span>+</span><span>
</span><span># move the x axis labels up top</span><span>
</span><span>scale_x_discrete</span><span>(</span><span>position</span><span> </span><span>=</span><span> </span><span>&quot;top&quot;</span><span>)</span><span> </span><span>+</span><span>
</span><span>theme_bw</span><span>()</span><span> </span><span>+</span><span>
</span><span># Format tweaks</span><span>
</span><span># Remove the legend</span><span>
</span><span>theme</span><span>(</span><span>legend.position</span><span> </span><span>=</span><span> </span><span>&quot;none&quot;</span><span>)</span><span> </span><span>+</span><span>
</span><span># Remove the panel border</span><span>
</span><span>theme</span><span>(</span><span>panel.border</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span># Remove just about everything from the y axis</span><span>
</span><span>theme</span><span>(</span><span>axis.title.y</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span>theme</span><span>(</span><span>axis.text.y</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span>theme</span><span>(</span><span>panel.grid.major.y</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span>theme</span><span>(</span><span>panel.grid.minor.y</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span># Remove a few things from the x axis and increase font size</span><span>
</span><span>theme</span><span>(</span><span>axis.title.x</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span>theme</span><span>(</span><span>panel.grid.major.x</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span>theme</span><span>(</span><span>axis.text.x.top</span><span> </span><span>=</span><span> </span><span>element_text</span><span>(</span><span>size</span><span>=</span><span>12</span><span>))</span><span> </span><span>+</span><span>
</span><span># Remove x &amp; y tick marks</span><span>
</span><span>theme</span><span>(</span><span>axis.ticks</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span># Format title &amp; subtitle</span><span>
</span><span>theme</span><span>(</span><span>plot.title</span><span> </span><span>=</span><span> </span><span>element_text</span><span>(</span><span>size</span><span>=</span><span>14</span><span>,</span><span> </span><span>face</span><span> </span><span>=</span><span> </span><span>&quot;bold&quot;</span><span>,</span><span> </span><span>hjust</span><span> </span><span>=</span><span> </span><span>0.5</span><span>))</span><span> </span><span>+</span><span>
</span><span>theme</span><span>(</span><span>plot.subtitle</span><span> </span><span>=</span><span> </span><span>element_text</span><span>(</span><span>hjust</span><span> </span><span>=</span><span> </span><span>0.5</span><span>))</span><span> </span><span>+</span><span>
</span><span># Labelling as desired</span><span>
</span><span>labs</span><span>(</span><span>
</span><span>title</span><span> </span><span>=</span><span> </span><span>&quot;Voter's stated preferences for June 7 elections in Ontario&quot;</span><span>,</span><span>
</span><span>subtitle</span><span> </span><span>=</span><span> </span><span>&quot;(Mainstreet Research)&quot;</span><span>,</span><span>
</span><span>caption</span><span> </span><span>=</span><span> </span><span>&quot;https://www.mainstreetresearch.ca/gap-between-ndp-and-pcs-narrows-while-liberals-hold-steady/&quot;</span><span>
</span><span>)</span><span>
</span></code></pre>
</div>
</div>
<p><img alt="" src="https://i1.wp.com/ibecav.github.io/images/slopegraph1d-1.png?w=456" data-recalc-dims="1"></p>
<p>Eureka! Not perfect yet but definitely looking good.</p>
<h2>Adding complexity</h2>
<p>I’m feeling pretty good about the solution so far but there are three<br>
things I’d like to make better.</p>
<ol>
<li>How well will this solution work when we have more than two time<br>
periods? Need to make sure it generalizes to a more complex case.</li>
<li>As <a rel="nofollow" href="https://www.r-bloggers.com/author/murtaza-haider/" target="_blank">Murtaza<br>
Haider</a> notes in<br>
his post we’ll have issues if the data points are identical or very<br>
close together. Our very neat little labels will overlap each other.<br>
In his post I believe he mentions that he manually moved them in<br>
some cases. Let’s try and fix that.</li>
<li>Oh my, that’s a lot of code to keep cutting and pasting, can we<br>
simplify?</li>
</ol>
<p>To test #1 and #2 I have “invented”” a new dataset called <code>moredata</code>.<br>
<strong>It is fictional</strong> it’s labelled May 25th but today is actually May<br>
24th. But I created it to add a third polling date and to make sure that<br>
we had a chance to test what happens when we have two identical<br>
datapoints on the same day. Notice that on May 25th the polling numbers<br>
for the Liberals and the NDP are identical at<br>
26.8%.</p>
<div>
<div>
<pre><code><span>moredata</span><span> </span><span>&lt;-</span><span> </span><span>structure</span><span>(</span><span>list</span><span>(</span><span>Date</span><span> </span><span>=</span><span> </span><span>structure</span><span>(</span><span>c</span><span>(</span><span>1L</span><span>,</span><span> </span><span>1L</span><span>,</span><span> </span><span>1L</span><span>,</span><span> </span><span>1L</span><span>,</span><span> </span><span>1L</span><span>,</span><span> </span><span>2L</span><span>,</span><span> </span><span>2L</span><span>,</span><span> </span><span>2L</span><span>,</span><span> </span><span>2L</span><span>,</span><span> </span><span>2L</span><span>,</span><span> </span><span>3L</span><span>,</span><span> </span><span>3L</span><span>,</span><span> </span><span>3L</span><span>,</span><span> </span><span>3L</span><span>,</span><span> </span><span>3L</span><span>),</span><span> </span><span>.Label</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>&quot;11-May-18&quot;</span><span>,</span><span> </span><span>&quot;18-May-18&quot;</span><span>,</span><span> </span><span>&quot;25-May-18&quot;</span><span>),</span><span> </span><span>class</span><span> </span><span>=</span><span> </span><span>&quot;factor&quot;</span><span>),</span><span> </span><span>Party</span><span> </span><span>=</span><span> </span><span>structure</span><span>(</span><span>c</span><span>(</span><span>5L</span><span>,</span><span> </span><span>3L</span><span>,</span><span> </span><span>2L</span><span>,</span><span> </span><span>1L</span><span>,</span><span> </span><span>4L</span><span>,</span><span> </span><span>5L</span><span>,</span><span> </span><span>3L</span><span>,</span><span> </span><span>2L</span><span>,</span><span> </span><span>1L</span><span>,</span><span> </span><span>4L</span><span>,</span><span> </span><span>5L</span><span>,</span><span> </span><span>3L</span><span>,</span><span> </span><span>2L</span><span>,</span><span> </span><span>1L</span><span>,</span><span> </span><span>4L</span><span>),</span><span> </span><span>.Label</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>&quot;Green&quot;</span><span>,</span><span> </span><span>&quot;Liberal&quot;</span><span>,</span><span> </span><span>&quot;NDP&quot;</span><span>,</span><span> </span><span>&quot;Others&quot;</span><span>,</span><span> </span><span>&quot;PC&quot;</span><span>),</span><span> </span><span>class</span><span> </span><span>=</span><span> </span><span>&quot;factor&quot;</span><span>),</span><span> </span><span>Pct</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>42.3</span><span>,</span><span> </span><span>28.4</span><span>,</span><span> </span><span>22.1</span><span>,</span><span> </span><span>5.4</span><span>,</span><span> </span><span>1.8</span><span>,</span><span> </span><span>41.9</span><span>,</span><span> </span><span>29.3</span><span>,</span><span> </span><span>22.3</span><span>,</span><span> </span><span>5</span><span>,</span><span> </span><span>1.4</span><span>,</span><span> </span><span>41.9</span><span>,</span><span> </span><span>26.8</span><span>,</span><span> </span><span>26.8</span><span>,</span><span> </span><span>5</span><span>,</span><span> </span><span>1.4</span><span>)),</span><span> </span><span>class</span><span> </span><span>=</span><span> </span><span>&quot;data.frame&quot;</span><span>,</span><span> </span><span>row.names</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>NA</span><span>,</span><span> </span><span>-15L</span><span>))</span><span>
</span><span>tail</span><span>(</span><span>moredata</span><span>)</span><span>
</span></code></pre>
</div>
</div>
<div>
<div>
<pre><code>##         Date   Party  Pct
## 10 18-May-18  Others  1.4
## 11 25-May-18      PC 41.9
## 12 25-May-18     NDP 26.8
## 13 25-May-18 Liberal 26.8
## 14 25-May-18   Green  5.0
## 15 25-May-18  Others  1.4
</code></pre>
</div>
</div>
<p>You’ll notice at the beginning of this post I loaded the <code>ggrepel</code><br>
library. <code>ggrepel</code> works with <code>ggplot2</code> to <em>repel</em> things that overlap,<br>
in this case our <code>geom_text</code> labels. The invocation is <code>geom_text_repel</code><br>
and it is very similar to <code>geom_text</code> but allows us to deconflict the<br>
overlaps. We’ll use <code>hjust = &quot;left&quot;</code> and <code>hjust = &quot;right&quot;</code> to control<br>
justifying the labels. We’ll use a fixed nudge left and right <code>nudge_x =<br>
-.45</code> and <code>nudge_x = .5</code> to move the labels left and right off the<br>
plotted data points and we will explicitly tell <code>geom_text_repel</code> to<br>
only move the labels vertically to avoid overlap with <code>direction = &quot;y&quot;</code>.<br>
Everything else remains the same.</p>
<div>
<div>
<pre><code><span>ggplot</span><span>(</span><span>data</span><span> </span><span>=</span><span> </span><span>moredata</span><span>,</span><span> </span><span>aes</span><span>(</span><span>x</span><span> </span><span>=</span><span> </span><span>Date</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>Pct</span><span>,</span><span> </span><span>group</span><span> </span><span>=</span><span> </span><span>Party</span><span>))</span><span> </span><span>+</span><span>
</span><span>geom_line</span><span>(</span><span>aes</span><span>(</span><span>color</span><span> </span><span>=</span><span> </span><span>Party</span><span>,</span><span> </span><span>alpha</span><span> </span><span>=</span><span> </span><span>1</span><span>),</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>2</span><span>)</span><span> </span><span>+</span><span>
</span><span>geom_point</span><span>(</span><span>aes</span><span>(</span><span>color</span><span> </span><span>=</span><span> </span><span>Party</span><span>,</span><span> </span><span>alpha</span><span> </span><span>=</span><span> </span><span>1</span><span>),</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>4</span><span>)</span><span> </span><span>+</span><span>
</span><span>geom_text_repel</span><span>(</span><span>data</span><span> </span><span>=</span><span> </span><span>moredata</span><span> </span><span>%>%</span><span> </span><span>filter</span><span>(</span><span>Date</span><span> </span><span>==</span><span> </span><span>&quot;11-May-18&quot;</span><span>),</span><span> </span><span>aes</span><span>(</span><span>label</span><span> </span><span>=</span><span> </span><span>paste0</span><span>(</span><span>Party</span><span>,</span><span> </span><span>&quot; - &quot;</span><span>,</span><span> </span><span>Pct</span><span>,</span><span> </span><span>&quot;%&quot;</span><span>))</span><span> </span><span>,</span><span> </span><span>hjust</span><span> </span><span>=</span><span> </span><span>&quot;left&quot;</span><span>,</span><span> </span><span>fontface</span><span> </span><span>=</span><span> </span><span>&quot;bold&quot;</span><span>,</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>4</span><span>,</span><span> </span><span>nudge_x</span><span> </span><span>=</span><span> </span><span>-.45</span><span>,</span><span> </span><span>direction</span><span> </span><span>=</span><span> </span><span>&quot;y&quot;</span><span>)</span><span> </span><span>+</span><span>
</span><span>geom_text_repel</span><span>(</span><span>data</span><span> </span><span>=</span><span> </span><span>moredata</span><span> </span><span>%>%</span><span> </span><span>filter</span><span>(</span><span>Date</span><span> </span><span>==</span><span> </span><span>&quot;25-May-18&quot;</span><span>),</span><span> </span><span>aes</span><span>(</span><span>label</span><span> </span><span>=</span><span> </span><span>paste0</span><span>(</span><span>Party</span><span>,</span><span> </span><span>&quot; - &quot;</span><span>,</span><span> </span><span>Pct</span><span>,</span><span> </span><span>&quot;%&quot;</span><span>))</span><span> </span><span>,</span><span> </span><span>hjust</span><span> </span><span>=</span><span> </span><span>&quot;right&quot;</span><span>,</span><span> </span><span>fontface</span><span> </span><span>=</span><span> </span><span>&quot;bold&quot;</span><span>,</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>4</span><span>,</span><span> </span><span>nudge_x</span><span> </span><span>=</span><span> </span><span>.5</span><span>,</span><span> </span><span>direction</span><span> </span><span>=</span><span> </span><span>&quot;y&quot;</span><span>)</span><span> </span><span>+</span><span>
</span><span># move the x axis labels up top</span><span>
</span><span>scale_x_discrete</span><span>(</span><span>position</span><span> </span><span>=</span><span> </span><span>&quot;top&quot;</span><span>)</span><span> </span><span>+</span><span>
</span><span>theme_bw</span><span>()</span><span> </span><span>+</span><span>
</span><span># Format tweaks</span><span>
</span><span># Remove the legend</span><span>
</span><span>theme</span><span>(</span><span>legend.position</span><span> </span><span>=</span><span> </span><span>&quot;none&quot;</span><span>)</span><span> </span><span>+</span><span>
</span><span># Remove the panel border</span><span>
</span><span>theme</span><span>(</span><span>panel.border</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span># Remove just about everything from the y axis</span><span>
</span><span>theme</span><span>(</span><span>axis.title.y</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span>theme</span><span>(</span><span>axis.text.y</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span>theme</span><span>(</span><span>panel.grid.major.y</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span>theme</span><span>(</span><span>panel.grid.minor.y</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span># Remove a few things from the x axis and increase font size</span><span>
</span><span>theme</span><span>(</span><span>axis.title.x</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span>theme</span><span>(</span><span>panel.grid.major.x</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span>theme</span><span>(</span><span>axis.text.x.top</span><span> </span><span>=</span><span> </span><span>element_text</span><span>(</span><span>size</span><span>=</span><span>12</span><span>))</span><span> </span><span>+</span><span>
</span><span># Remove x &amp; y tick marks</span><span>
</span><span>theme</span><span>(</span><span>axis.ticks</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>())</span><span> </span><span>+</span><span>
</span><span># Format title &amp; subtitle</span><span>
</span><span>theme</span><span>(</span><span>plot.title</span><span> </span><span>=</span><span> </span><span>element_text</span><span>(</span><span>size</span><span>=</span><span>14</span><span>,</span><span> </span><span>face</span><span> </span><span>=</span><span> </span><span>&quot;bold&quot;</span><span>,</span><span> </span><span>hjust</span><span> </span><span>=</span><span> </span><span>0.5</span><span>))</span><span> </span><span>+</span><span>
</span><span>theme</span><span>(</span><span>plot.subtitle</span><span> </span><span>=</span><span> </span><span>element_text</span><span>(</span><span>hjust</span><span> </span><span>=</span><span> </span><span>0.5</span><span>))</span><span> </span><span>+</span><span>
</span><span># Labelling as desired</span><span>
</span><span>labs</span><span>(</span><span>
</span><span>title</span><span> </span><span>=</span><span> </span><span>&quot;Bogus Data&quot;</span><span>,</span><span>
</span><span>subtitle</span><span> </span><span>=</span><span> </span><span>&quot;(Chuck Powell)&quot;</span><span>,</span><span>
</span><span>caption</span><span> </span><span>=</span><span> </span><span>&quot;https://www.mainstreetresearch.ca/gap-between-ndp-and-pcs-narrows-while-liberals-hold-steady/&quot;</span><span>
</span><span>)</span><span>
</span></code></pre>
</div>
</div>
<p><img alt="" src="https://i1.wp.com/ibecav.github.io/images/slopegraph2a-1.png?w=456" data-recalc-dims="1"></p>
<p>Very nice! We have confirmed that our solution works for more than two<br>
dates without any additional changes and we have found a solution to the<br>
label overlap issue. In a little while we’ll talk about labeling the<br>
data points in the center (if we want to).</p>
<p>Before we move on let’s make our life a little simpler. While the output<br>
plot is good it’s a lot of code to produce one graph. Let’s see if we<br>
can simplify…</p>
<p>Since ggplot2 objects are just regular R objects, you can put them in a<br>
list. This means you can apply all of R’s great functional programming<br>
tools. For example, if you wanted to add different geoms to the same<br>
base plot, you could put them in a list and use lapply().</p>
<p>But for now let’s at least take all the invariant lines of code and put<br>
them in a list. Then when we go to plot we can just invoke the list and<br>
remain confident we get the right formatting. For now let’s name this<br>
list something quaint and obvious like <code>MySpecial</code>.</p>
<div>
<div>
<pre><code><span>MySpecial</span><span> </span><span>&lt;-</span><span> </span><span>list</span><span>(</span><span> </span><span># move the x axis labels up top</span><span>
</span><span>scale_x_discrete</span><span>(</span><span>position</span><span> </span><span>=</span><span> </span><span>&quot;top&quot;</span><span>),</span><span>
</span><span>theme_bw</span><span>(),</span><span>
</span><span># Format tweaks</span><span>
</span><span># Remove the legend</span><span>
</span><span>theme</span><span>(</span><span>legend.position</span><span> </span><span>=</span><span> </span><span>&quot;none&quot;</span><span>),</span><span>
</span><span># Remove the panel border</span><span>
</span><span>theme</span><span>(</span><span>panel.border</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>()),</span><span>
</span><span># Remove just about everything from the y axis</span><span>
</span><span>theme</span><span>(</span><span>axis.title.y</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>()),</span><span>
</span><span>theme</span><span>(</span><span>axis.text.y</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>()),</span><span>
</span><span>theme</span><span>(</span><span>panel.grid.major.y</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>()),</span><span>
</span><span>theme</span><span>(</span><span>panel.grid.minor.y</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>()),</span><span>
</span><span># Remove a few things from the x axis and increase font size</span><span>
</span><span>theme</span><span>(</span><span>axis.title.x</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>()),</span><span>
</span><span>theme</span><span>(</span><span>panel.grid.major.x</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>()),</span><span>
</span><span>theme</span><span>(</span><span>axis.text.x.top</span><span> </span><span>=</span><span> </span><span>element_text</span><span>(</span><span>size</span><span>=</span><span>12</span><span>)),</span><span>
</span><span># Remove x &amp; y tick marks</span><span>
</span><span>theme</span><span>(</span><span>axis.ticks</span><span> </span><span>=</span><span> </span><span>element_blank</span><span>()),</span><span>
</span><span># Format title &amp; subtitle</span><span>
</span><span>theme</span><span>(</span><span>plot.title</span><span> </span><span>=</span><span> </span><span>element_text</span><span>(</span><span>size</span><span>=</span><span>14</span><span>,</span><span> </span><span>face</span><span> </span><span>=</span><span> </span><span>&quot;bold&quot;</span><span>,</span><span> </span><span>hjust</span><span> </span><span>=</span><span> </span><span>0.5</span><span>)),</span><span>
</span><span>theme</span><span>(</span><span>plot.subtitle</span><span> </span><span>=</span><span> </span><span>element_text</span><span>(</span><span>hjust</span><span> </span><span>=</span><span> </span><span>0.5</span><span>))</span><span>
</span><span>)</span><span>
</span><span>summary</span><span>(</span><span>MySpecial</span><span>)</span><span>
</span></code></pre>
</div>
</div>
<div>
<div>
<pre><code>##       Length Class                 Mode       
##  [1,] 17     ScaleDiscretePosition environment
##  [2,] 57     theme                 list       
##  [3,]  1     theme                 list       
##  [4,]  1     theme                 list       
##  [5,]  1     theme                 list       
##  [6,]  1     theme                 list       
##  [7,]  1     theme                 list       
##  [8,]  1     theme                 list       
##  [9,]  1     theme                 list       
## [10,]  1     theme                 list       
## [11,]  1     theme                 list       
## [12,]  1     theme                 list       
## [13,]  1     theme                 list       
## [14,]  1     theme                 list
</code></pre>
</div>
</div>
<p><code>MySpecial</code> is actually an incredibly complex structure so I used the<br>
<code>summary</code> function. What’s important to us is that in the future all we<br>
need to do is include it in the <code>ggplot</code> command and magic happens.<br>
Perhaps another day I’ll make it a proper function but for now I can<br>
change little things like line size or titles and labels without<br>
worrying about the rest. So here it is with some little things changed.</p>
<div>
<div>
<pre><code><span>ggplot</span><span>(</span><span>data</span><span> </span><span>=</span><span> </span><span>moredata</span><span>,</span><span> </span><span>aes</span><span>(</span><span>x</span><span> </span><span>=</span><span> </span><span>Date</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>Pct</span><span>,</span><span> </span><span>group</span><span> </span><span>=</span><span> </span><span>Party</span><span>))</span><span> </span><span>+</span><span>
</span><span>geom_line</span><span>(</span><span>aes</span><span>(</span><span>color</span><span> </span><span>=</span><span> </span><span>Party</span><span>,</span><span> </span><span>alpha</span><span> </span><span>=</span><span> </span><span>1</span><span>),</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>1</span><span>)</span><span> </span><span>+</span><span>
</span><span>geom_point</span><span>(</span><span>aes</span><span>(</span><span>color</span><span> </span><span>=</span><span> </span><span>Party</span><span>,</span><span> </span><span>alpha</span><span> </span><span>=</span><span> </span><span>1</span><span>),</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>3</span><span>)</span><span> </span><span>+</span><span>
</span><span>geom_text_repel</span><span>(</span><span>data</span><span> </span><span>=</span><span> </span><span>moredata</span><span> </span><span>%>%</span><span> </span><span>filter</span><span>(</span><span>Date</span><span> </span><span>==</span><span> </span><span>&quot;11-May-18&quot;</span><span>),</span><span> </span><span>aes</span><span>(</span><span>label</span><span> </span><span>=</span><span> </span><span>paste0</span><span>(</span><span>Party</span><span>,</span><span> </span><span>&quot; : &quot;</span><span>,</span><span> </span><span>Pct</span><span>,</span><span> </span><span>&quot;%&quot;</span><span>))</span><span> </span><span>,</span><span> </span><span>hjust</span><span> </span><span>=</span><span> </span><span>&quot;left&quot;</span><span>,</span><span> </span><span>fontface</span><span> </span><span>=</span><span> </span><span>&quot;bold&quot;</span><span>,</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>4</span><span>,</span><span> </span><span>nudge_x</span><span> </span><span>=</span><span> </span><span>-.45</span><span>,</span><span> </span><span>direction</span><span> </span><span>=</span><span> </span><span>&quot;y&quot;</span><span>)</span><span> </span><span>+</span><span>
</span><span>geom_text_repel</span><span>(</span><span>data</span><span> </span><span>=</span><span> </span><span>moredata</span><span> </span><span>%>%</span><span> </span><span>filter</span><span>(</span><span>Date</span><span> </span><span>==</span><span> </span><span>&quot;25-May-18&quot;</span><span>),</span><span> </span><span>aes</span><span>(</span><span>label</span><span> </span><span>=</span><span> </span><span>paste0</span><span>(</span><span>Party</span><span>,</span><span> </span><span>&quot; : &quot;</span><span>,</span><span> </span><span>Pct</span><span>,</span><span> </span><span>&quot;%&quot;</span><span>))</span><span> </span><span>,</span><span> </span><span>hjust</span><span> </span><span>=</span><span> </span><span>&quot;right&quot;</span><span>,</span><span> </span><span>fontface</span><span> </span><span>=</span><span> </span><span>&quot;bold&quot;</span><span>,</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>4</span><span>,</span><span> </span><span>nudge_x</span><span> </span><span>=</span><span> </span><span>.5</span><span>,</span><span> </span><span>direction</span><span> </span><span>=</span><span> </span><span>&quot;y&quot;</span><span>)</span><span> </span><span>+</span><span>
</span><span>MySpecial</span><span> </span><span>+</span><span>
</span><span>labs</span><span>(</span><span>
</span><span>title</span><span> </span><span>=</span><span> </span><span>&quot;Bogus Data&quot;</span><span>,</span><span>
</span><span>subtitle</span><span> </span><span>=</span><span> </span><span>&quot;(Chuck Powell)&quot;</span><span>,</span><span>
</span><span>caption</span><span> </span><span>=</span><span> </span><span>&quot;https://www.mainstreetresearch.ca/gap-between-ndp-and-pcs-narrows-while-liberals-hold-steady/&quot;</span><span>
</span><span>)</span><span>
</span></code></pre>
</div>
</div>
<p><img alt="" src="https://i1.wp.com/ibecav.github.io/images/slopegraph3a-1.png?w=456" data-recalc-dims="1"></p>
<h2>Even more complex</h2>
<p>Feeling good about the solution so far I decided to press on to a much<br>
more complex problem. <a rel="nofollow" href="https://github.com/leeper" target="_blank">Thomas J. Leeper</a> has<br>
a nice plot of <a rel="nofollow" href="https://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=0003nk" target="_blank">Tufte’s Cancer survival<br>
slopegraph</a><br>
<strong>N.B. that the original Tufte is not accurate on the vertical scale.<br>
Look at Prostate and Thyroid for example since visually I would argue<br>
they should cross to reflect the data</strong>.</p>
<p>Let’s grab the data as laid out by<br>
Tufte.</p>
<div>
<div>
<pre><code><span>cancer</span><span> </span><span>&lt;-</span><span> </span><span>structure</span><span>(</span><span>list</span><span>(</span><span>Year.5</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>99</span><span>,</span><span> </span><span>96</span><span>,</span><span> </span><span>95</span><span>,</span><span> </span><span>89</span><span>,</span><span> </span><span>86</span><span>,</span><span> </span><span>85</span><span>,</span><span> </span><span>84</span><span>,</span><span> </span><span>82</span><span>,</span><span> </span><span>71</span><span>,</span><span> </span><span>69</span><span>,</span><span> </span><span>63</span><span>,</span><span> </span><span>62</span><span>,</span><span> </span><span>62</span><span>,</span><span> </span><span>58</span><span>,</span><span> </span><span>57</span><span>,</span><span> </span><span>55</span><span>,</span><span> </span><span>43</span><span>,</span><span> </span><span>32</span><span>,</span><span> </span><span>30</span><span>,</span><span> </span><span>24</span><span>,</span><span> </span><span>15</span><span>,</span><span> </span><span>14</span><span>,</span><span> </span><span>8</span><span>,</span><span> </span><span>4</span><span>),</span><span> </span><span>Year.10</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>95</span><span>,</span><span> </span><span>96</span><span>,</span><span> </span><span>94</span><span>,</span><span> </span><span>87</span><span>,</span><span> </span><span>78</span><span>,</span><span> </span><span>80</span><span>,</span><span> </span><span>83</span><span>,</span><span> </span><span>76</span><span>,</span><span> </span><span>64</span><span>,</span><span> </span><span>57</span><span>,</span><span> </span><span>55</span><span>,</span><span> </span><span>54</span><span>,</span><span> </span><span>55</span><span>,</span><span> </span><span>46</span><span>,</span><span> </span><span>46</span><span>,</span><span> </span><span>49</span><span>,</span><span> </span><span>32</span><span>,</span><span> </span><span>29</span><span>,</span><span> </span><span>13</span><span>,</span><span> </span><span>19</span><span>,</span><span> </span><span>11</span><span>,</span><span> </span><span>8</span><span>,</span><span> </span><span>6</span><span>,</span><span> </span><span>3</span><span>),</span><span> </span><span>Year.15</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>87</span><span>,</span><span> </span><span>94</span><span>,</span><span> </span><span>91</span><span>,</span><span> </span><span>84</span><span>,</span><span> </span><span>71</span><span>,</span><span> </span><span>74</span><span>,</span><span> </span><span>81</span><span>,</span><span> </span><span>70</span><span>,</span><span> </span><span>63</span><span>,</span><span> </span><span>46</span><span>,</span><span> </span><span>52</span><span>,</span><span> </span><span>50</span><span>,</span><span> </span><span>54</span><span>,</span><span> </span><span>38</span><span>,</span><span> </span><span>38</span><span>,</span><span> </span><span>50</span><span>,</span><span> </span><span>30</span><span>,</span><span> </span><span>28</span><span>,</span><span> </span><span>7</span><span>,</span><span> </span><span>19</span><span>,</span><span> </span><span>7</span><span>,</span><span> </span><span>8</span><span>,</span><span> </span><span>6</span><span>,</span><span> </span><span>3</span><span>),</span><span> </span><span>Year.20</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>81</span><span>,</span><span> </span><span>95</span><span>,</span><span> </span><span>88</span><span>,</span><span> </span><span>83</span><span>,</span><span> </span><span>75</span><span>,</span><span> </span><span>67</span><span>,</span><span> </span><span>79</span><span>,</span><span> </span><span>68</span><span>,</span><span> </span><span>60</span><span>,</span><span> </span><span>38</span><span>,</span><span> </span><span>49</span><span>,</span><span> </span><span>47</span><span>,</span><span> </span><span>52</span><span>,</span><span> </span><span>34</span><span>,</span><span> </span><span>33</span><span>,</span><span> </span><span>50</span><span>,</span><span> </span><span>26</span><span>,</span><span> </span><span>26</span><span>,</span><span> </span><span>5</span><span>,</span><span> </span><span>15</span><span>,</span><span> </span><span>6</span><span>,</span><span> </span><span>5</span><span>,</span><span> </span><span>8</span><span>,</span><span> </span><span>3</span><span>)),</span><span> </span><span>class</span><span> </span><span>=</span><span> </span><span>&quot;data.frame&quot;</span><span>,</span><span> </span><span>row.names</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>&quot;Prostate&quot;</span><span>,</span><span> </span><span>&quot;Thyroid&quot;</span><span>,</span><span> </span><span>&quot;Testis&quot;</span><span>,</span><span> </span><span>&quot;Melanomas&quot;</span><span>,</span><span> </span><span>&quot;Breast&quot;</span><span>,</span><span> </span><span>&quot;Hodgkin's&quot;</span><span>,</span><span> </span><span>&quot;Uterus&quot;</span><span>,</span><span> </span><span>&quot;Urinary&quot;</span><span>,</span><span> </span><span>&quot;Cervix&quot;</span><span>,</span><span> </span><span>&quot;Larynx&quot;</span><span>,</span><span> </span><span>&quot;Rectum&quot;</span><span>,</span><span> </span><span>&quot;Kidney&quot;</span><span>,</span><span> </span><span>&quot;Colon&quot;</span><span>,</span><span> </span><span>&quot;Non-Hodgkin's&quot;</span><span>,</span><span> </span><span>&quot;Oral&quot;</span><span>,</span><span> </span><span>&quot;Ovary&quot;</span><span>,</span><span> </span><span>&quot;Leukemia&quot;</span><span>,</span><span> </span><span>&quot;Brain&quot;</span><span>,</span><span> </span><span>&quot;Multiple myeloma&quot;</span><span>,</span><span> </span><span>&quot;Stomach&quot;</span><span>,</span><span> </span><span>&quot;Lung&quot;</span><span>,</span><span> </span><span>&quot;Esophagus&quot;</span><span>,</span><span> </span><span>&quot;Liver&quot;</span><span>,</span><span> </span><span>&quot;Pancreas&quot;</span><span>))</span><span>
</span><span>str</span><span>(</span><span>cancer</span><span>)</span><span>
</span></code></pre>
</div>
</div>
<div>
<div>
<pre><code>## 'data.frame':    24 obs. of  4 variables:
##  $ Year.5 : num  99 96 95 89 86 85 84 82 71 69 ...
##  $ Year.10: num  95 96 94 87 78 80 83 76 64 57 ...
##  $ Year.15: num  87 94 91 84 71 74 81 70 63 46 ...
##  $ Year.20: num  81 95 88 83 75 67 79 68 60 38 ...
</code></pre>
</div>
</div>
<div>
<div>
<pre><code><span>kable</span><span>(</span><span>head</span><span>(</span><span>cancer</span><span>,</span><span>10</span><span>))</span><span> </span><span>%>%</span><span> </span><span>kable_styling</span><span>(</span><span>bootstrap_options</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>&quot;striped&quot;</span><span>,</span><span> </span><span>&quot;hover&quot;</span><span>,</span><span> </span><span>&quot;condensed&quot;</span><span>,</span><span> </span><span>&quot;responsive&quot;</span><span>))</span><span>
</span></code></pre>
</div>
</div>
<table>
<thead>
<tr>
<th>
</th>
<th>
<p>Year.5</p>
</th>
<th>
<p>Year.10</p>
</th>
<th>
<p>Year.15</p>
</th>
<th>
<p>Year.20</p>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p>Prostate</p>
</td>
<td>
<p>99</p>
</td>
<td>
<p>95</p>
</td>
<td>
<p>87</p>
</td>
<td>
<p>81</p>
</td>
</tr>
<tr>
<td>
<p>Thyroid</p>
</td>
<td>
<p>96</p>
</td>
<td>
<p>96</p>
</td>
<td>
<p>94</p>
</td>
<td>
<p>95</p>
</td>
</tr>
<tr>
<td>
<p>Testis</p>
</td>
<td>
<p>95</p>
</td>
<td>
<p>94</p>
</td>
<td>
<p>91</p>
</td>
<td>
<p>88</p>
</td>
</tr>
<tr>
<td>
<p>Melanomas</p>
</td>
<td>
<p>89</p>
</td>
<td>
<p>87</p>
</td>
<td>
<p>84</p>
</td>
<td>
<p>83</p>
</td>
</tr>
<tr>
<td>
<p>Breast</p>
</td>
<td>
<p>86</p>
</td>
<td>
<p>78</p>
</td>
<td>
<p>71</p>
</td>
<td>
<p>75</p>
</td>
</tr>
<tr>
<td>
<p>Hodgkin’s</p>
</td>
<td>
<p>85</p>
</td>
<td>
<p>80</p>
</td>
<td>
<p>74</p>
</td>
<td>
<p>67</p>
</td>
</tr>
<tr>
<td>
<p>Uterus</p>
</td>
<td>
<p>84</p>
</td>
<td>
<p>83</p>
</td>
<td>
<p>81</p>
</td>
<td>
<p>79</p>
</td>
</tr>
<tr>
<td>
<p>Urinary</p>
</td>
<td>
<p>82</p>
</td>
<td>
<p>76</p>
</td>
<td>
<p>70</p>
</td>
<td>
<p>68</p>
</td>
</tr>
<tr>
<td>
<p>Cervix</p>
</td>
<td>
<p>71</p>
</td>
<td>
<p>64</p>
</td>
<td>
<p>63</p>
</td>
<td>
<p>60</p>
</td>
</tr>
<tr>
<td>
<p>Larynx</p>
</td>
<td>
<p>69</p>
</td>
<td>
<p>57</p>
</td>
<td>
<p>46</p>
</td>
<td>
<p>38</p>
</td>
</tr>
</tbody>
</table>
<p>There, we have it in a neat data frame but not organized as we need it.<br>
Not unusual, and an opportunity to use some other tools from <code>broom</code> and<br>
<code>reshape2</code>. Let’s do the following:</p>
<ol>
<li>Let’s transpose the data with <code>t</code></li>
<li>Let’s use <code>broom::fix_data_frame</code> to get valid column names and<br>
convert rownames to a proper column all in one function. Right now<br>
the types of cancer are nothing but rownames.</li>
<li>Use <code>reshape2::melt</code> to take our transposed dataframe and convert it<br>
to long format so we can send it off to <code>ggplot</code>. Along the way<br>
we’ll rename the resulting dataframe <code>newcancer</code> with columns<br>
named <code>Year</code>, <code>Type</code> and <code>Survival</code>.</li>
</ol>
<p></p>
<div>
<div>
<pre><code><span># stepping through for demonstration purposes</span><span>
</span><span>t</span><span>(</span><span>cancer</span><span>)</span><span> </span><span># returns a matrix</span><span>
</span></code></pre>
</div>
</div>
<div>
<div>
<pre><code>##         Prostate Thyroid Testis Melanomas Breast Hodgkin's Uterus Urinary
## Year.5        99      96     95        89     86        85     84      82
## Year.10       95      96     94        87     78        80     83      76
## Year.15       87      94     91        84     71        74     81      70
## Year.20       81      95     88        83     75        67     79      68
##         Cervix Larynx Rectum Kidney Colon Non-Hodgkin's Oral Ovary
## Year.5      71     69     63     62    62            58   57    55
## Year.10     64     57     55     54    55            46   46    49
## Year.15     63     46     52     50    54            38   38    50
## Year.20     60     38     49     47    52            34   33    50
##         Leukemia Brain Multiple myeloma Stomach Lung Esophagus Liver
## Year.5        43    32               30      24   15        14     8
## Year.10       32    29               13      19   11         8     6
## Year.15       30    28                7      19    7         8     6
## Year.20       26    26                5      15    6         5     8
##         Pancreas
## Year.5         4
## Year.10        3
## Year.15        3
## Year.20        3
</code></pre>
</div>
</div>
<div>
<div>
<pre><code><span>broom</span><span>::</span><span>fix_data_frame</span><span>(</span><span>
</span><span>t</span><span>(</span><span>cancer</span><span>),</span><span> </span><span>newcol</span><span> </span><span>=</span><span> </span><span>&quot;Year&quot;</span><span>)</span><span> </span><span># make it a dataframe with Year as a proper column</span><span>
</span></code></pre>
</div>
</div>
<div>
<div>
<pre><code>##      Year Prostate Thyroid Testis Melanomas Breast Hodgkin.s Uterus
## 1  Year.5       99      96     95        89     86        85     84
## 2 Year.10       95      96     94        87     78        80     83
## 3 Year.15       87      94     91        84     71        74     81
## 4 Year.20       81      95     88        83     75        67     79
##   Urinary Cervix Larynx Rectum Kidney Colon Non.Hodgkin.s Oral Ovary
## 1      82     71     69     63     62    62            58   57    55
## 2      76     64     57     55     54    55            46   46    49
## 3      70     63     46     52     50    54            38   38    50
## 4      68     60     38     49     47    52            34   33    50
##   Leukemia Brain Multiple.myeloma Stomach Lung Esophagus Liver Pancreas
## 1       43    32               30      24   15        14     8        4
## 2       32    29               13      19   11         8     6        3
## 3       30    28                7      19    7         8     6        3
## 4       26    26                5      15    6         5     8        3
</code></pre>
</div>
</div>
<div>
<div>
<pre><code><span>reshape2</span><span>::</span><span>melt</span><span>(</span><span>
</span><span>broom</span><span>::</span><span>fix_data_frame</span><span>(</span><span>
</span><span>t</span><span>(</span><span>cancer</span><span>),</span><span> </span><span>newcol</span><span> </span><span>=</span><span> </span><span>&quot;Year&quot;</span><span>),</span><span> </span><span>id</span><span>=</span><span>&quot;Year&quot;</span><span>,</span><span> </span><span>variable.name</span><span>=</span><span>&quot;Type&quot;</span><span>,</span><span> </span><span>value.name</span><span> </span><span>=</span><span> </span><span>&quot;Survival&quot;</span><span>)</span><span> </span><span># melt it to long form</span><span>
</span></code></pre>
</div>
</div>
<div>
<div>
<pre><code>##       Year             Type Survival
## 1   Year.5         Prostate       99
## 2  Year.10         Prostate       95
## 3  Year.15         Prostate       87
## 4  Year.20         Prostate       81
## 5   Year.5          Thyroid       96
## 6  Year.10          Thyroid       96
## 7  Year.15          Thyroid       94
## 8  Year.20          Thyroid       95
## 9   Year.5           Testis       95
## 10 Year.10           Testis       94
## 11 Year.15           Testis       91
## 12 Year.20           Testis       88
## 13  Year.5        Melanomas       89
## 14 Year.10        Melanomas       87
## 15 Year.15        Melanomas       84
## 16 Year.20        Melanomas       83
## 17  Year.5           Breast       86
## 18 Year.10           Breast       78
## 19 Year.15           Breast       71
## 20 Year.20           Breast       75
## 21  Year.5        Hodgkin.s       85
## 22 Year.10        Hodgkin.s       80
## 23 Year.15        Hodgkin.s       74
## 24 Year.20        Hodgkin.s       67
## 25  Year.5           Uterus       84
## 26 Year.10           Uterus       83
## 27 Year.15           Uterus       81
## 28 Year.20           Uterus       79
## 29  Year.5          Urinary       82
## 30 Year.10          Urinary       76
## 31 Year.15          Urinary       70
## 32 Year.20          Urinary       68
## 33  Year.5           Cervix       71
## 34 Year.10           Cervix       64
## 35 Year.15           Cervix       63
## 36 Year.20           Cervix       60
## 37  Year.5           Larynx       69
## 38 Year.10           Larynx       57
## 39 Year.15           Larynx       46
## 40 Year.20           Larynx       38
## 41  Year.5           Rectum       63
## 42 Year.10           Rectum       55
## 43 Year.15           Rectum       52
## 44 Year.20           Rectum       49
## 45  Year.5           Kidney       62
## 46 Year.10           Kidney       54
## 47 Year.15           Kidney       50
## 48 Year.20           Kidney       47
## 49  Year.5            Colon       62
## 50 Year.10            Colon       55
## 51 Year.15            Colon       54
## 52 Year.20            Colon       52
## 53  Year.5    Non.Hodgkin.s       58
## 54 Year.10    Non.Hodgkin.s       46
## 55 Year.15    Non.Hodgkin.s       38
## 56 Year.20    Non.Hodgkin.s       34
## 57  Year.5             Oral       57
## 58 Year.10             Oral       46
## 59 Year.15             Oral       38
## 60 Year.20             Oral       33
## 61  Year.5            Ovary       55
## 62 Year.10            Ovary       49
## 63 Year.15            Ovary       50
## 64 Year.20            Ovary       50
## 65  Year.5         Leukemia       43
## 66 Year.10         Leukemia       32
## 67 Year.15         Leukemia       30
## 68 Year.20         Leukemia       26
## 69  Year.5            Brain       32
## 70 Year.10            Brain       29
## 71 Year.15            Brain       28
## 72 Year.20            Brain       26
## 73  Year.5 Multiple.myeloma       30
## 74 Year.10 Multiple.myeloma       13
## 75 Year.15 Multiple.myeloma        7
## 76 Year.20 Multiple.myeloma        5
## 77  Year.5          Stomach       24
## 78 Year.10          Stomach       19
## 79 Year.15          Stomach       19
## 80 Year.20          Stomach       15
## 81  Year.5             Lung       15
## 82 Year.10             Lung       11
## 83 Year.15             Lung        7
## 84 Year.20             Lung        6
## 85  Year.5        Esophagus       14
## 86 Year.10        Esophagus        8
## 87 Year.15        Esophagus        8
## 88 Year.20        Esophagus        5
## 89  Year.5            Liver        8
## 90 Year.10            Liver        6
## 91 Year.15            Liver        6
## 92 Year.20            Liver        8
## 93  Year.5         Pancreas        4
## 94 Year.10         Pancreas        3
## 95 Year.15         Pancreas        3
## 96 Year.20         Pancreas        3
</code></pre>
</div>
</div>
<div>
<div>
<pre><code><span># all those steps in one long line saved to a new dataframe</span><span>
</span><span>newcancer</span><span> </span><span>&lt;-</span><span> </span><span>reshape2</span><span>::</span><span>melt</span><span>(</span><span>broom</span><span>::</span><span>fix_data_frame</span><span>(</span><span>t</span><span>(</span><span>cancer</span><span>),</span><span> </span><span>newcol</span><span> </span><span>=</span><span> </span><span>&quot;Year&quot;</span><span>),</span><span> </span><span>id</span><span>=</span><span>&quot;Year&quot;</span><span>,</span><span> </span><span>variable.name</span><span>=</span><span>&quot;Type&quot;</span><span>,</span><span> </span><span>value.name</span><span> </span><span>=</span><span> </span><span>&quot;Survival&quot;</span><span>)</span><span>
</span></code></pre>
</div>
</div>
<p>Now we have whipped the data into the shape we need it. 96 rows with the<br>
three columns we want to plot, <code>Year</code>, <code>Type</code>, and <code>Survival</code>. If you<br>
look at the data though, you’ll notice two small faults. First, <code>Year</code><br>
is not a <code>factor</code>. The plot will work but have an annoying limitation.<br>
Since “Year.5” is a character string it will be ordered after all the<br>
other years. We could fix that on the fly within our <code>ggplot</code> call but I<br>
find it cleaner and more understandable if I take care of that first.<br>
I’ll use the <code>factor</code> function from base <code>R</code> to accomplish that and<br>
while I’m at it make the values nicer looking. Second in three cases <code>R</code><br>
changed cancer type names because they couldn’t be column names in a<br>
dataframe. I’ll use <code>forcats::fct_recode</code> to make them look better.</p>
<div>
<div>
<pre><code><span>newcancer</span><span>$</span><span>Year</span><span> </span><span>&lt;-</span><span> </span><span>factor</span><span>(</span><span>newcancer</span><span>$</span><span>Year</span><span>,</span><span> </span><span>levels</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>&quot;Year.5&quot;</span><span>,</span><span> </span><span>&quot;Year.10&quot;</span><span>,</span><span> </span><span>&quot;Year.15&quot;</span><span>,</span><span> </span><span>&quot;Year.20&quot;</span><span>),</span><span> </span><span>labels</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>&quot;5 Year&quot;</span><span>,</span><span>&quot;10 Year&quot;</span><span>,</span><span>&quot;15 Year&quot;</span><span>,</span><span>&quot;20 Year&quot;</span><span>),</span><span> </span><span>ordered</span><span> </span><span>=</span><span> </span><span>TRUE</span><span>)</span><span>
</span><span>newcancer</span><span>$</span><span>Type</span><span> </span><span>&lt;-</span><span> </span><span>forcats</span><span>::</span><span>fct_recode</span><span>(</span><span>newcancer</span><span>$</span><span>Type</span><span>,</span><span> </span><span>&quot;Hodgkin's&quot;</span><span> </span><span>=</span><span> </span><span>&quot;Hodgkin.s&quot;</span><span>,</span><span> </span><span>&quot;Non-Hodgkin's&quot;</span><span> </span><span>=</span><span> </span><span>&quot;Non.Hodgkin.s&quot;</span><span>,</span><span> </span><span>&quot;Multiple myeloma&quot;</span><span> </span><span>=</span><span> </span><span>&quot;Multiple.myeloma&quot;</span><span>)</span><span>
</span><span>head</span><span>(</span><span>newcancer</span><span>)</span><span>
</span></code></pre>
</div>
</div>
<div>
<div>
<pre><code>##      Year     Type Survival
## 1  5 Year Prostate       99
## 2 10 Year Prostate       95
## 3 15 Year Prostate       87
## 4 20 Year Prostate       81
## 5  5 Year  Thyroid       96
## 6 10 Year  Thyroid       96
</code></pre>
</div>
</div>
<p>Now that we have the data the way we want it we can make our slopegraph.<br>
Some of the necessary changes are obvious <code>x = Year</code>, <code>y = Survival</code> and<br>
<code>group = Type</code> for example. Since there are a lot of plotted lines I’ve<br>
reduced the weight or size of the individual lines. We no longer want to<br>
plot the big round points, we’re going to substitute in the actual<br>
numbers, so that line gets commented out. The left and right labels<br>
require no change and <code>geom_text_repel</code> will keep them from overlapping<br>
which is almost inevitable given the data. To put the actual survival<br>
numbers on the plot we’ll turn to <code>geom_label</code>. It’s like <code>geom_text</code><br>
only it puts a label box around the text. We’ll choose a smallish size,<br>
minimize the amount of padding, and make the border of the box<br>
invisible. The end result is what we want. It overlays on top of the<br>
lines we’ve already plotted and the invisible padding gives us just<br>
enough room.</p>
<div>
<div>
<pre><code><span>ggplot</span><span>(</span><span>data</span><span> </span><span>=</span><span> </span><span>newcancer</span><span>,</span><span> </span><span>aes</span><span>(</span><span>x</span><span> </span><span>=</span><span> </span><span>Year</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>Survival</span><span>,</span><span> </span><span>group</span><span> </span><span>=</span><span> </span><span>Type</span><span>))</span><span> </span><span>+</span><span>
</span><span>geom_line</span><span>(</span><span>aes</span><span>(</span><span>color</span><span> </span><span>=</span><span> </span><span>Type</span><span>,</span><span> </span><span>alpha</span><span> </span><span>=</span><span> </span><span>1</span><span>),</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>1</span><span>)</span><span> </span><span>+</span><span>
</span><span># geom_point(aes(color = Type, alpha = .1), size = 4) +</span><span>
</span><span>geom_text_repel</span><span>(</span><span>data</span><span> </span><span>=</span><span> </span><span>newcancer</span><span> </span><span>%>%</span><span> </span><span>filter</span><span>(</span><span>Year</span><span> </span><span>==</span><span> </span><span>&quot;5 Year&quot;</span><span>),</span><span> </span><span>aes</span><span>(</span><span>label</span><span> </span><span>=</span><span> </span><span>Type</span><span>)</span><span> </span><span>,</span><span> </span><span>hjust</span><span> </span><span>=</span><span> </span><span>&quot;left&quot;</span><span>,</span><span> </span><span>fontface</span><span> </span><span>=</span><span> </span><span>&quot;bold&quot;</span><span>,</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>3</span><span>,</span><span> </span><span>nudge_x</span><span> </span><span>=</span><span> </span><span>-.45</span><span>,</span><span> </span><span>direction</span><span> </span><span>=</span><span> </span><span>&quot;y&quot;</span><span>)</span><span> </span><span>+</span><span>
</span><span>geom_text_repel</span><span>(</span><span>data</span><span> </span><span>=</span><span> </span><span>newcancer</span><span> </span><span>%>%</span><span> </span><span>filter</span><span>(</span><span>Year</span><span> </span><span>==</span><span> </span><span>&quot;20 Year&quot;</span><span>),</span><span> </span><span>aes</span><span>(</span><span>label</span><span> </span><span>=</span><span> </span><span>Type</span><span>)</span><span> </span><span>,</span><span> </span><span>hjust</span><span> </span><span>=</span><span> </span><span>&quot;right&quot;</span><span>,</span><span> </span><span>fontface</span><span> </span><span>=</span><span> </span><span>&quot;bold&quot;</span><span>,</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>3</span><span>,</span><span> </span><span>nudge_x</span><span> </span><span>=</span><span> </span><span>.5</span><span>,</span><span> </span><span>direction</span><span> </span><span>=</span><span> </span><span>&quot;y&quot;</span><span>)</span><span> </span><span>+</span><span>
</span><span>geom_label</span><span>(</span><span>aes</span><span>(</span><span>label</span><span> </span><span>=</span><span> </span><span>Survival</span><span>),</span><span> </span><span>size</span><span> </span><span>=</span><span> </span><span>2.5</span><span>,</span><span> </span><span>label.padding</span><span> </span><span>=</span><span> </span><span>unit</span><span>(</span><span>0.05</span><span>,</span><span> </span><span>&quot;lines&quot;</span><span>),</span><span> </span><span>label.size</span><span> </span><span>=</span><span> </span><span>0.0</span><span>)</span><span> </span><span>+</span><span>
</span><span>MySpecial</span><span> </span><span>+</span><span>
</span><span>labs</span><span>(</span><span>
</span><span>title</span><span> </span><span>=</span><span> </span><span>&quot;Estimates of Percent Survival Rates&quot;</span><span>,</span><span>
</span><span>subtitle</span><span> </span><span>=</span><span> </span><span>&quot;Based on: Edward Tufte, Beautiful Evidence, 174, 176.&quot;</span><span>,</span><span>
</span><span>caption</span><span> </span><span>=</span><span> </span><span>&quot;https://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=0003nk&quot;</span><span>
</span><span>)</span><span>
</span></code></pre>
</div>
</div>
<p><img alt="" src="https://i0.wp.com/ibecav.github.io/images/slopegraph4c-1.png?w=456" data-recalc-dims="1"></p>
<h2>Done for now</h2>
<p>I hope you’ve found this useful. I am always open to comments,<br>
corrections and suggestions.</p>
<p>Chuck (ibecav at gmail dot<br>
com)</p>
<h3>License</h3>
<p><a rel="nofollow" href="http://creativecommons.org/licenses/by-sa/4.0/" target="_blank"><img alt="Creative Commons License" src="https://i1.wp.com/i.creativecommons.org/l/by-sa/4.0/88x31.png?w=456&ssl=1" data-recalc-dims="1"></a><br>This<br>
work is licensed under a<br>
<a rel="nofollow" href="http://creativecommons.org/licenses/by-sa/4.0/" target="_blank">Creative<br>
Commons Attribution-ShareAlike 4.0 International License</a>.</p>
	<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://ibecav.github.io/slopegraph/"> Chuck Powell</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a rel="nofollow" href="https://www.r-project.org/" title="The R Project for Statistical Computing">R</a> news and <a rel="nofollow" href="https://www.r-bloggers.com/search/tutorial" title="R tutorials">tutorials</a> on topics such as: <a rel="nofollow" href="https://www.r-bloggers.com/search/data%20science" title="Data science">Data science</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data" title="Big Data">Big Data, <a rel="nofollow" href="https://www.r-users.com/" title="R jobs">R jobs</a>, visualization (<a rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2" title="ggplot and ggplot2 tutorials">ggplot2</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/boxplot" title="Boxplots using lattice and ggplot2 tutorials">Boxplots</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/map" title="Maps and gis">maps</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/animation" title="Animation in R">animation</a>), programming (<a rel="nofollow" href="https://www.r-bloggers.com/search/RStudio" title="RStudio IDE for R">RStudio</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/sweave" title="Sweave and literate programming">Sweave</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX" title="LaTeX in R">LaTeX</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/SQL" title="SQL and databases">SQL</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/eclipse" title="Eclipse IDE for R">Eclipse</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/git" title="git and github, Version Control System">git</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/hadoop" title="Large data in R using Hadoop">hadoop</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping" title="Web Scraping of google, facebook, yahoo, twitter and more using R">Web Scraping</a>) statistics (<a rel="nofollow" href="https://www.r-bloggers.com/search/regression" title="Regressions and ANOVA analysis tutorials">regression</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/PCA" title="principal component analysis tutorial">PCA</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/time+series" title="Time series">time series</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/trading" title="finance trading">trading</a>) and more...
<img width="1" alt="" src="http://feeds.feedburner.com/~r/RBloggers/~4/OPK99GBf14k" height="1"></a></div>