<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/visualising-residuals/"></div></div><div><a data-url="https://www.r-bloggers.com/visualising-residuals/" data-counturl="https://www.r-bloggers.com/visualising-residuals/" data-count="horizontal" data-text="Visualising Residuals" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://drsimonj.svbtle.com/visualising-residuals"> blogR</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>Residuals. Now there’s something to get you out of bed in the morning!</p>
<p>OK, maybe residuals aren’t the sexiest topic in the world. Still, they’re an essential element and means for identifying potential problems of any statistical model. For example, the residuals from a linear regression model should be <a target="_blank" href="https://en.wikipedia.org/wiki/Homoscedasticity">homoscedastic</a>. If not, this indicates an issue with the model such as non-linearity in the data.</p>
<p>This post will cover various methods for visualising residuals from regression-based models. Here are some examples of the visualisations that we’ll be creating:</p>
<p><a target="_blank" href="https://i1.wp.com/svbtleusercontent.com/9jiwlvibugesq.png?ssl=1"><img alt="init-example1-1.png" src="https://i1.wp.com/svbtleusercontent.com/9jiwlvibugesq_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p><a target="_blank" href="https://i2.wp.com/svbtleusercontent.com/ofplwqnv83y06a.png?ssl=1"><img alt="init-example2-1.png" src="https://i1.wp.com/svbtleusercontent.com/ofplwqnv83y06a_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p><a target="_blank" href="https://i2.wp.com/svbtleusercontent.com/d9zosqjlgsoqw.png?ssl=1"><img alt="init-example3-1.png" src="https://i1.wp.com/svbtleusercontent.com/d9zosqjlgsoqw_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<h2><a target="_blank" href="http://drsimonj.svbtle.com/visualising-residuals#what-you-need-to-know_2"> </a>What you need to know</h2>
<p>To get the most out of this post, there are a few things you should be aware of. Firstly, if you’re unfamiliar with the meaning of residuals, or what seems to be going on here, I’d recommend that you first do some introductory reading on the topic. Some places to get started are <a target="_blank" href="https://en.wikipedia.org/wiki/Errors_and_residuals">Wikipedia</a> and this excellent section on <a target="_blank" href="http://docs.statwing.com/interpreting-residual-plots-to-improve-your-regression/">Statwing</a>.</p>
<p>You’ll also need to be familiar with running regression (linear and logistic) in R, and using the following packages: <a target="_blank" href="https://cran.r-project.org/web/packages/ggplot2/index.html">ggplot2</a> to produce all graphics, and <a target="_blank" href="https://cran.r-project.org/web/packages/dplyr/index.html">dplyr</a> and <a target="_blank" href="https://cran.r-project.org/web/packages/tidyr/index.html">tidyr</a> to do data manipulation. In most cases, you should be able to follow along with each step, but it will help if you’re already familiar with these.</p>
<h2><a target="_blank" href="http://drsimonj.svbtle.com/visualising-residuals#what-we39ve-got-already_2"> </a>What we’ve got already</h2>
<p>Before diving in, it’s good to remind ourselves of the default options that R has for visualising residuals. Most notably, we can directly <code>plot()</code> a fitted regression model. For example, using the <code>mtcars</code> data set, let’s regress the number of miles per gallon for each car (<code>mpg</code>) on their horsepower (<code>hp</code>) and visualise information about the model and residuals:</p>
<pre><code>fit &lt;- lm(mpg ~ hp, data = mtcars)  # Fit the model
summary(fit)  # Report the results
#> 
#> Call:
#> lm(formula = mpg ~ hp, data = mtcars)
#> 
#> Residuals:
#>     Min      1Q  Median      3Q     Max 
#> -5.7121 -2.1122 -0.8854  1.5819  8.2360 
#> 
#> Coefficients:
#>             Estimate Std. Error t value Pr(>|t|)    
#> (Intercept) 30.09886    1.63392  18.421  &lt; 2e-16 ***
#> hp          -0.06823    0.01012  -6.742 1.79e-07 ***
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> Residual standard error: 3.863 on 30 degrees of freedom
#> Multiple R-squared:  0.6024, Adjusted R-squared:  0.5892 
#> F-statistic: 45.46 on 1 and 30 DF,  p-value: 1.788e-07

par(mfrow = c(2, 2))  # Split the plotting panel into a 2 x 2 grid
plot(fit)  # Plot the model information
</code></pre>
<p><a target="_blank" href="https://i1.wp.com/svbtleusercontent.com/vjxchzokiifcrg.png?ssl=1"><img alt="unnamed-chunk-2-1.png" src="https://i2.wp.com/svbtleusercontent.com/vjxchzokiifcrg_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<pre><code>par(mfrow = c(1, 1))  # Return plotting panel to 1 section
</code></pre>
<p>These plots provide a traditional method to interpret residual terms and determine whether there might be problems with our model. We’ll now be thinking about how to supplement these with some alternative (and more visually appealing) graphics.</p>
<h2><a target="_blank" href="http://drsimonj.svbtle.com/visualising-residuals#general-approach_2"> </a>General Approach</h2>
<p>The general approach behind each of the examples that we’ll cover below is to:</p>
<ol>
<li> Fit a regression model to predict variable (Y).</li>
<li> Obtain the predicted and residual values associated with each observation on (Y).</li>
<li> Plot the actual and predicted values of (Y) so that they are distinguishable, but connected.</li>
<li> Use the residuals to make an aesthetic adjustment (e.g. red colour when residual in very high) to highlight points which are poorly predicted by the model.</li>
</ol>
<h2><a target="_blank" href="http://drsimonj.svbtle.com/visualising-residuals#simple-linear-regression_2"> </a>Simple Linear Regression</h2>
<p>We’ll start with simple linear regression, which is when we regress one variable on just one other. We can take the earlier example, where we regressed miles per gallon on horsepower.</p>
<h3><a target="_blank" href="http://drsimonj.svbtle.com/visualising-residuals#step-1-fit-the-model_3"> </a>Step 1: fit the model</h3>
<p>First, we will fit our model. In this instance, let’s copy the <code>mtcars</code> dataset to a new object <code>d</code> so we can manipulate it later:</p>
<pre><code>d &lt;- mtcars
fit &lt;- lm(mpg ~ hp, data = d)
</code></pre>
<h3><a target="_blank" href="http://drsimonj.svbtle.com/visualising-residuals#step-2-obtain-predicted-and-residual-values_3"> </a>Step 2: obtain predicted and residual values</h3>
<p>Next, we want to get predicted and residual values to add supplementary information to this graph. We can do this as follows:</p>
<pre><code>d$predicted &lt;- predict(fit)   # Save the predicted values
d$residuals &lt;- residuals(fit) # Save the residual values

# Quick look at the actual, predicted, and residual values
library(dplyr)
d %>% select(mpg, predicted, residuals) %>% head()
#>                    mpg predicted  residuals
#> Mazda RX4         21.0  22.59375 -1.5937500
#> Mazda RX4 Wag     21.0  22.59375 -1.5937500
#> Datsun 710        22.8  23.75363 -0.9536307
#> Hornet 4 Drive    21.4  22.59375 -1.1937500
#> Hornet Sportabout 18.7  18.15891  0.5410881
#> Valiant           18.1  22.93489 -4.8348913
</code></pre>
<p>Looking good so far.</p>
<h3><a target="_blank" href="http://drsimonj.svbtle.com/visualising-residuals#step-3-plot-the-actual-and-predicted-values_3"> </a>Step 3: plot the actual and predicted values</h3>
<p>Plotting these values takes a couple of intermediate steps. First, we plot our actual data as follows:</p>
<pre><code>library(ggplot2)
ggplot(d, aes(x = hp, y = mpg)) +  # Set up canvas with outcome variable on y-axis
  geom_point()  # Plot the actual points
</code></pre>
<p><a target="_blank" href="https://i0.wp.com/svbtleusercontent.com/yfe1ecancpsuoa.png?ssl=1"><img alt="unnamed-chunk-5-1.png" src="https://i1.wp.com/svbtleusercontent.com/yfe1ecancpsuoa_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p>Next, we plot the predicted values in a way that they’re distinguishable from the actual values. For example, let’s change their shape:</p>
<pre><code>ggplot(d, aes(x = hp, y = mpg)) +
  geom_point() +
  geom_point(aes(y = predicted), shape = 1)  # Add the predicted values
</code></pre>
<p><a target="_blank" href="https://i2.wp.com/svbtleusercontent.com/do8hz1nwz0lcza.png?ssl=1"><img alt="unnamed-chunk-6-1.png" src="https://i0.wp.com/svbtleusercontent.com/do8hz1nwz0lcza_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p>This is on track, but it’s difficult to see how our actual and predicted values are related. Let’s connect the actual data points with their corresponding predicted value using <code>geom_segment()</code>:</p>
<pre><code>ggplot(d, aes(x = hp, y = mpg)) +
  geom_segment(aes(xend = hp, yend = predicted)) +
  geom_point() +
  geom_point(aes(y = predicted), shape = 1)
</code></pre>
<p><a target="_blank" href="https://i0.wp.com/svbtleusercontent.com/3lrkoicgjyoww.png?ssl=1"><img alt="unnamed-chunk-7-1.png" src="https://i0.wp.com/svbtleusercontent.com/3lrkoicgjyoww_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p>We’ll make a few final adjustments:</p>
<ul>
<li> Clean up the overall look with <code>theme_bw()</code>.</li>
<li> Fade out connection lines by adjusting their <code>alpha</code>.</li>
<li> Add the regression slope with <code>geom_smooth()</code>:</li>
</ul>
<pre><code>library(ggplot2)
ggplot(d, aes(x = hp, y = mpg)) +
  geom_smooth(method = &quot;lm&quot;, se = FALSE, color = &quot;lightgrey&quot;) +  # Plot regression slope
  geom_segment(aes(xend = hp, yend = predicted), alpha = .2) +  # alpha to fade lines
  geom_point() +
  geom_point(aes(y = predicted), shape = 1) +
  theme_bw()  # Add theme for cleaner look
</code></pre>
<p><a target="_blank" href="https://i0.wp.com/svbtleusercontent.com/hxpz3t38nc5q0w.png?ssl=1"><img alt="unnamed-chunk-8-1.png" src="https://i0.wp.com/svbtleusercontent.com/hxpz3t38nc5q0w_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<h3><a target="_blank" href="http://drsimonj.svbtle.com/visualising-residuals#step-4-use-residuals-to-adjust_3"> </a>Step 4: use residuals to adjust</h3>
<p>Finally, we want to make an adjustment to highlight the size of the residual. There are MANY options. To make comparisons easy, I’ll make adjustments to the actual values, but you could just as easily apply these, or other changes, to the predicted values. Here are a few examples building on the previous plot:</p>
<pre><code># ALPHA
# Changing alpha of actual values based on absolute value of residuals
ggplot(d, aes(x = hp, y = mpg)) +
  geom_smooth(method = &quot;lm&quot;, se = FALSE, color = &quot;lightgrey&quot;) +
  geom_segment(aes(xend = hp, yend = predicted), alpha = .2) +

  # > Alpha adjustments made here...
  geom_point(aes(alpha = abs(residuals))) +  # Alpha mapped to abs(residuals)
  guides(alpha = FALSE) +  # Alpha legend removed
  # &lt;

  geom_point(aes(y = predicted), shape = 1) +
  theme_bw()
</code></pre>
<p><a target="_blank" href="https://i1.wp.com/svbtleusercontent.com/vpanyo8pesanzg.png?ssl=1"><img alt="unnamed-chunk-9-1.png" src="https://i2.wp.com/svbtleusercontent.com/vpanyo8pesanzg_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<pre><code>
# COLOR
# High residuals (in abolsute terms) made more red on actual values.
ggplot(d, aes(x = hp, y = mpg)) +
  geom_smooth(method = &quot;lm&quot;, se = FALSE, color = &quot;lightgrey&quot;) +
  geom_segment(aes(xend = hp, yend = predicted), alpha = .2) +

  # > Color adjustments made here...
  geom_point(aes(color = abs(residuals))) + # Color mapped to abs(residuals)
  scale_color_continuous(low = &quot;black&quot;, high = &quot;red&quot;) +  # Colors to use here
  guides(color = FALSE) +  # Color legend removed
  # &lt;

  geom_point(aes(y = predicted), shape = 1) +
  theme_bw()
</code></pre>
<p><a target="_blank" href="https://i1.wp.com/svbtleusercontent.com/1zym4jjjdx1tga.png?ssl=1"><img alt="unnamed-chunk-9-2.png" src="https://i1.wp.com/svbtleusercontent.com/1zym4jjjdx1tga_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<pre><code>

# SIZE AND COLOR
# Same coloring as above, size corresponding as well
ggplot(d, aes(x = hp, y = mpg)) +
  geom_smooth(method = &quot;lm&quot;, se = FALSE, color = &quot;lightgrey&quot;) +
  geom_segment(aes(xend = hp, yend = predicted), alpha = .2) +

  # > Color AND size adjustments made here...
  geom_point(aes(color = abs(residuals), size = abs(residuals))) + # size also mapped
  scale_color_continuous(low = &quot;black&quot;, high = &quot;red&quot;) +
  guides(color = FALSE, size = FALSE) +  # Size legend also removed
  # &lt;

  geom_point(aes(y = predicted), shape = 1) +
  theme_bw()
</code></pre>
<p><a target="_blank" href="https://i2.wp.com/svbtleusercontent.com/0peiwblkjqn08a.png?ssl=1"><img alt="unnamed-chunk-9-3.png" src="https://i0.wp.com/svbtleusercontent.com/0peiwblkjqn08a_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<pre><code>
# COLOR UNDER/OVER
# Color mapped to residual with sign taken into account.
# i.e., whether actual value is greater or less than predicted
ggplot(d, aes(x = hp, y = mpg)) +
  geom_smooth(method = &quot;lm&quot;, se = FALSE, color = &quot;lightgrey&quot;) +
  geom_segment(aes(xend = hp, yend = predicted), alpha = .2) +

  # > Color adjustments made here...
  geom_point(aes(color = residuals)) +  # Color mapped here
  scale_color_gradient2(low = &quot;blue&quot;, mid = &quot;white&quot;, high = &quot;red&quot;) +  # Colors to use here
  guides(color = FALSE) +
  # &lt;

  geom_point(aes(y = predicted), shape = 1) +
  theme_bw()
</code></pre>
<p><a target="_blank" href="https://i2.wp.com/svbtleusercontent.com/nlvizgyehjzia.png?ssl=1"><img alt="unnamed-chunk-9-4.png" src="https://i1.wp.com/svbtleusercontent.com/nlvizgyehjzia_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p>I particularly like this last example, because the colours nicely help to identify non-linearity in the data. For example, we can see that there is more red for extreme values of <code>hp</code> where the actual values are greater than what is being predicted. There is more blue in the centre, however, indicating that the actual values are less than what is being predicted. Together, this suggests that the relationship between the variables is non-linear, and might be better modelled by including a quadratic term in the regression equation.</p>
<h2><a target="_blank" href="http://drsimonj.svbtle.com/visualising-residuals#multiple-regression_2"> </a>Multiple Regression</h2>
<p>Let’s crank up the complexity and get into multiple regression, where we regress one variable on two or more others. For this example, we’ll regress Miles per gallon (<code>mpg</code>) on horsepower (<code>hp</code>), weight (<code>wt</code>), and displacement (<code>disp</code>).</p>
<pre><code># Select out data of interest:
d &lt;- mtcars %>% select(mpg, hp, wt, disp)

# Fit the model
fit &lt;- lm(mpg ~ hp + wt+ disp, data = d)

# Obtain predicted and residual values
d$predicted &lt;- predict(fit)
d$residuals &lt;- residuals(fit)

head(d)
#>                    mpg  hp    wt disp predicted  residuals
#> Mazda RX4         21.0 110 2.620  160  23.57003 -2.5700299
#> Mazda RX4 Wag     21.0 110 2.875  160  22.60080 -1.6008028
#> Datsun 710        22.8  93 2.320  108  25.28868 -2.4886829
#> Hornet 4 Drive    21.4 110 3.215  258  21.21667  0.1833269
#> Hornet Sportabout 18.7 175 3.440  360  18.24072  0.4592780
#> Valiant           18.1 105 3.460  225  20.47216 -2.3721590
</code></pre>
<p>Let’s create a relevant plot using ONE of our predictors, horsepower (<code>hp</code>). Again, we’ll start by plotting the actual and predicted values. In this case, plotting the regression slope is a little more complicated, so we’ll exclude it to stay on focus.</p>
<pre><code>ggplot(d, aes(x = hp, y = mpg)) +
  geom_segment(aes(xend = hp, yend = predicted), alpha = .2) +  # Lines to connect points
  geom_point() +  # Points of actual values
  geom_point(aes(y = predicted), shape = 1) +  # Points of predicted values
  theme_bw()
</code></pre>
<p><a target="_blank" href="https://i0.wp.com/svbtleusercontent.com/ylfjppwlk6aavw.png?ssl=1"><img alt="unnamed-chunk-11-1.png" src="https://i2.wp.com/svbtleusercontent.com/ylfjppwlk6aavw_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p>Again, we can make all sorts of adjustments using the residual values. Let’s apply the same changes as the last plot above – with blue or red for actual values that are greater or less than their predicted values:</p>
<pre><code>ggplot(d, aes(x = hp, y = mpg)) +
  geom_segment(aes(xend = hp, yend = predicted), alpha = .2) +
  geom_point(aes(color = residuals)) +
  scale_color_gradient2(low = &quot;blue&quot;, mid = &quot;white&quot;, high = &quot;red&quot;) +
  guides(color = FALSE) +
  geom_point(aes(y = predicted), shape = 1) +
  theme_bw()
</code></pre>
<p><a target="_blank" href="https://i2.wp.com/svbtleusercontent.com/igtzhkdbi4a1ya.png?ssl=1"><img alt="unnamed-chunk-12-1.png" src="https://i1.wp.com/svbtleusercontent.com/igtzhkdbi4a1ya_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p>So far, there’s not anything new in our code. All that has changed in that the predicted values don’t line up neatly because we’re now doing multiple regression.</p>
<h3><a target="_blank" href="http://drsimonj.svbtle.com/visualising-residuals#plotting-multiple-predictors-at-once_3"> </a>Plotting multiple predictors at once</h3>
<p>Plotting one independent variable is all well and good, but the whole point of multiple regression is to investigate multiple variables!</p>
<p>To visualise this, we’ll make use of one of my favourite tricks: using the tidyr package to <code>gather()</code> our independent variable columns, and then use <code>facet_*()</code> in our ggplot to split them into separate panels. For relevant examples, see <a target="_blank" href="https://drsimonj.svbtle.com/plotting-background-data-for-groups-with-ggplot2">here</a>, <a target="_blank" href="https://drsimonj.svbtle.com/plot-some-variables-against-many-others">here</a>, or <a target="_blank" href="https://drsimonj.svbtle.com/quick-plot-of-all-variables">here</a>.</p>
<p>Let’s recreate the last example plot, but separately for each of our predictor variables.</p>
<pre><code>d %>% 
  gather(key = &quot;iv&quot;, value = &quot;x&quot;, -mpg, -predicted, -residuals) %>%  # Get data into shape
  ggplot(aes(x = x, y = mpg)) +  # Note use of `x` here and next line
  geom_segment(aes(xend = x, yend = predicted), alpha = .2) +
  geom_point(aes(color = residuals)) +
  scale_color_gradient2(low = &quot;blue&quot;, mid = &quot;white&quot;, high = &quot;red&quot;) +
  guides(color = FALSE) +
  geom_point(aes(y = predicted), shape = 1) +
  facet_grid(~ iv, scales = &quot;free&quot;) +  # Split panels here by `iv`
  theme_bw()
</code></pre>
<p><a target="_blank" href="https://i2.wp.com/svbtleusercontent.com/ycfceqsiozowsw.png?ssl=1"><img alt="unnamed-chunk-13-1.png" src="https://i0.wp.com/svbtleusercontent.com/ycfceqsiozowsw_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p>Let’s try this out with another data set. We’ll use the <code>iris</code> data set, and regress <code>Sepal.Width</code> on all other variables (including the categorical variable, <code>species</code>):</p>
<pre><code>d &lt;- iris

# Fit the model
fit &lt;- lm(Sepal.Width ~ ., data = iris)

# Obtain predicted and residual values
d$predicted &lt;- predict(fit)
d$residuals &lt;- residuals(fit)

# Create plot
d %>% 
  gather(key = &quot;iv&quot;, value = &quot;x&quot;, -Sepal.Width, -predicted, -residuals) %>%
  ggplot(aes(x = x, y = Sepal.Width)) +
  geom_segment(aes(xend = x, yend = predicted), alpha = .2) +
  geom_point(aes(color = residuals)) +
  scale_color_gradient2(low = &quot;blue&quot;, mid = &quot;white&quot;, high = &quot;red&quot;) +
  guides(color = FALSE) +
  geom_point(aes(y = predicted), shape = 1) +
  facet_grid(~ iv, scales = &quot;free&quot;) +
  theme_bw()
</code></pre>
<p><a target="_blank" href="https://i1.wp.com/svbtleusercontent.com/d2fv5p06kn3q.png?ssl=1"><img alt="unnamed-chunk-14-1.png" src="https://i1.wp.com/svbtleusercontent.com/d2fv5p06kn3q_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p>To make this plot, after the regression, the only change to our previous code was to change <code>mpg</code> to <code>Sepal.Width</code> in two places: the <code>gather()</code> and <code>ggplot()</code> lines.</p>
<p>We can now see how the actual and predicted values compare across our predictor variables. In case you’d forgotten, the coloured points are the actual data, and the white circles are the predicted values. With this in mind, we can see, as expected, that there is less variability in the predicted values than the actual values. It also appears that the sepal width of the setosa species is not as well accounted for as the other species.</p>
<h2><a target="_blank" href="http://drsimonj.svbtle.com/visualising-residuals#logistic-regression_2"> </a>Logistic Regression</h2>
<p>To round this post off, let’s extend our approach to logistic regression. It’s going to require the same basic workflow, but we will need to extract predicted and residual values for the responses. Here’s an example predicting V/S (<code>vs</code>), which is 0 or 1, with <code>hp</code>:</p>
<pre><code># Step 1: Fit the data
d &lt;- mtcars
fit &lt;- glm(vs ~ hp, family = binomial(), data = d)

# Step 2: Obtain predicted and residuals
d$predicted &lt;- predict(fit, type=&quot;response&quot;)
d$residuals &lt;- residuals(fit, type = &quot;response&quot;)

# Steps 3 and 4: plot the results
ggplot(d, aes(x = hp, y = vs)) +
  geom_segment(aes(xend = hp, yend = predicted), alpha = .2) +
  geom_point(aes(color = residuals)) +
  scale_color_gradient2(low = &quot;blue&quot;, mid = &quot;white&quot;, high = &quot;red&quot;) +
  guides(color = FALSE) +
  geom_point(aes(y = predicted), shape = 1) +
  theme_bw()
</code></pre>
<p><a target="_blank" href="https://i2.wp.com/svbtleusercontent.com/d1z8mezu6how.png?ssl=1"><img alt="unnamed-chunk-15-1.png" src="https://i1.wp.com/svbtleusercontent.com/d1z8mezu6how_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p>If we only want to flag cases that would be scored as the incorrect category, we can do something like the following (with some help from the dplyr function, <code>filter()</code>):</p>
<pre><code>ggplot(d, aes(x = hp, y = vs)) +
  geom_segment(aes(xend = hp, yend = predicted), alpha = .2) +
  geom_point() +

  # > This plots large red circle on misclassified points
  geom_point(data = d %>% filter(vs != round(predicted)),
             color = &quot;red&quot;, size = 2) +
  # &lt;

  scale_color_gradient2(low = &quot;blue&quot;, mid = &quot;white&quot;, high = &quot;red&quot;) +
  guides(color = FALSE) +
  geom_point(aes(y = predicted), shape = 1) +
  theme_bw()
</code></pre>
<p><a target="_blank" href="https://i1.wp.com/svbtleusercontent.com/rvllcikr3oohww.png?ssl=1"><img alt="unnamed-chunk-16-1.png" src="https://i1.wp.com/svbtleusercontent.com/rvllcikr3oohww_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p>I’ll leave it to you to combine this with instructions from the previous sections if you’d like to extend it to multiple logistic regression. But, hopefully, you should now have a good idea of the steps involved and how to create these residual visualisations!</p>
<h2><a target="_blank" href="http://drsimonj.svbtle.com/visualising-residuals#sign-off_2"> </a>Sign off</h2>
<p>Thanks for reading and I hope this was useful for you.</p>
<p>For updates of recent blog posts, follow <a target="_blank" href="https://twitter.com/drsimonj">@drsimonj</a> on Twitter, or email me at <a target="_blank" href="mailto:drsimonjackson@gmail.com">drsimonjackson@gmail.com</a> to get in touch.</p>
<p>If you’d like the code that produced this blog, check out the <a target="_blank" href="https://github.com/drsimonj/blogR">blogR GitHub repository</a>.</p>
<p><div><div><div><div data-width="55" data-show-faces="false" data-send="true" data-layout="box_count" data-height="62" data-href="https://www.r-bloggers.com/visualising-residuals/"></div></div><div><a data-url="https://www.r-bloggers.com/visualising-residuals/" data-counturl="https://www.r-bloggers.com/visualising-residuals/" data-count="vertical" data-text="Visualising Residuals" class="twitter-share-button" data-via="rbloggers" href="https://twitter.com/share"></a></div><div></div></div><div></div></div>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://drsimonj.svbtle.com/visualising-residuals"> blogR</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 title="The R Project for Statistical Computing" rel="nofollow" href="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/?s=data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/?s=Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/?s=map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/?s=animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/?s=RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/?s=sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/?s=LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/?s=SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/?s=eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/?s=git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/?s=hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/?s=Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/?s=regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/?s=PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/?s=time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/?s=trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/ho03dJtbl_I"></a></div>