<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/scatterplot-matrices-pair-plots-with-cdata-and-ggplot2/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://www.win-vector.com/blog/2018/10/scatterplot-matrices-pair-plots-with-cdata-and-ggplot2/"> R – Win-Vector Blog</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>In my <a rel="nofollow" href="http://www.win-vector.com/blog/2018/10/faceted-graphs-with-cdata-and-ggplot2/" target="_blank">previous post</a>, I showed how to use <a rel="nofollow" href="https://cran.r-project.org/package=cdata" target="_blank"><code>cdata</code></a> package along with <a rel="nofollow" href="https://cran.r-project.org/package=ggplot2" target="_blank"><code>ggplot2</code></a>‘s faceting facility to compactly plot two related graphs from the same data. This got me thinking: can I use <code>cdata</code> to produce a <code>ggplot2</code> version of a scatterplot matrix, or pairs plot?</p>
<p>A pairs plot compactly plots every (numeric) variable in a dataset against every other one. In base plot, you would use the <code>pairs()</code> function. Here is the base version of the pairs plot of the <code>iris</code> dataset:</p>
<div>
<pre><code><span>pairs</span>(iris[<span>1</span>:<span>4</span>], 
      <span>main =</span> <span>&quot;Anderson's Iris Data -- 3 species&quot;</span>,
      <span>pch =</span> <span>21</span>, 
      <span>bg =</span> <span>c</span>(<span>&quot;#1b9e77&quot;</span>, <span>&quot;#d95f02&quot;</span>, <span>&quot;#7570b3&quot;</span>)[<span>unclass</span>(iris$Species)])</code></pre>
</div>
<div>
<p><img border="0" src="https://i0.wp.com/www.win-vector.com/blog/wp-content/uploads/2018/10/unnamed-chunk-1-1-1.png?resize=660%2C471" alt="Unnamed chunk 1 1" width="450" data-recalc-dims="1"></p>
</div>
<p>There are other ways to do this, too:</p>
<div>
<pre><code><span># not run</span>

<span>library</span>(ggplot2)
<span>library</span>(GGally)
<span>ggpairs</span>(iris, <span>columns=</span><span>1</span>:<span>4</span>, <span>aes</span>(<span>color=</span>Species)) +<span> </span>
<span> </span><span>ggtitle</span>(<span>&quot;Anderson's Iris Data -- 3 species&quot;</span>)

<span>library</span>(lattice)
<span>splom</span>(iris[<span>1</span>:<span>4</span>], 
      <span>groups=</span>iris$Species, 
      <span>main=</span><span>&quot;Anderson's Iris Data -- 3 species&quot;</span>)</code></pre>
</div>
<p>But I wanted to see if <code>cdata</code> was up to the task. So here we go….</p>
<p><span></span></p>
<p>First, load the packages:</p>
<div>
<pre><code><span>library</span>(ggplot2)
<span>library</span>(cdata)</code></pre>
</div>
<p>To create the pairs plot in <code>ggplot2</code>, I need to reshape the data appropriately. For <code>cdata</code>, I need to specify what shape I want the data to be in, using a control table. See <a rel="nofollow" href="http://www.win-vector.com/blog/2018/10/faceted-graphs-with-cdata-and-ggplot2/" target="_blank">the last post</a> for how the control table works. For this task, creating the control table is slightly more involved.</p>
<p>Here, I specify the variables I want to plot.</p>
<div>
<pre><code>meas_vars &lt;-<span> </span><span>colnames</span>(iris)[<span>1</span>:<span>4</span>]</code></pre>
</div>
<p>The function <code>expand_grid()</code> returns a data frame of all combinations of its arguments; in this case, I want all pairs of variables.</p>
<div>
<pre><code><span># the data.frame() call strips the attributes from</span>
<span># the frame returned by expand.grid()</span>
controlTable &lt;-<span> </span><span>data.frame</span>(<span>expand.grid</span>(meas_vars, meas_vars, 
                                       <span>stringsAsFactors =</span> <span>FALSE</span>))
<span># rename the columns</span>
<span>colnames</span>(controlTable) &lt;-<span> </span><span>c</span>(<span>&quot;x&quot;</span>, <span>&quot;y&quot;</span>)

<span># add the key column</span>
controlTable &lt;-<span> </span><span>cbind</span>(
  <span>data.frame</span>(<span>pair_key =</span> <span>paste</span>(controlTable[[<span>1</span>]], controlTable[[<span>2</span>]]),
             <span>stringsAsFactors =</span> <span>FALSE</span>),
  controlTable)

controlTable</code></pre>
</div>
<pre><code>##                     pair_key            x            y
## 1  Sepal.Length Sepal.Length Sepal.Length Sepal.Length
## 2   Sepal.Width Sepal.Length  Sepal.Width Sepal.Length
## 3  Petal.Length Sepal.Length Petal.Length Sepal.Length
## 4   Petal.Width Sepal.Length  Petal.Width Sepal.Length
## 5   Sepal.Length Sepal.Width Sepal.Length  Sepal.Width
## 6    Sepal.Width Sepal.Width  Sepal.Width  Sepal.Width
## 7   Petal.Length Sepal.Width Petal.Length  Sepal.Width
## 8    Petal.Width Sepal.Width  Petal.Width  Sepal.Width
## 9  Sepal.Length Petal.Length Sepal.Length Petal.Length
## 10  Sepal.Width Petal.Length  Sepal.Width Petal.Length
## 11 Petal.Length Petal.Length Petal.Length Petal.Length
## 12  Petal.Width Petal.Length  Petal.Width Petal.Length
## 13  Sepal.Length Petal.Width Sepal.Length  Petal.Width
## 14   Sepal.Width Petal.Width  Sepal.Width  Petal.Width
## 15  Petal.Length Petal.Width Petal.Length  Petal.Width
## 16   Petal.Width Petal.Width  Petal.Width  Petal.Width</code></pre>
<p>The control table specifies that for every row of <code>iris</code>, sixteen new rows get produced, one for each possible pair of variables. The column <code>pair_key</code> will be the key column in the new data frame; there’s one key level for every possible pair of variables. The columns <code>x</code> and <code>y</code> will be the value columns in the new data frame — these will be the columns that we plot.</p>
<p>Now I can create the new data frame, using <code>rowrecs_to_blocks()</code>. I’ll also carry along the <code>Species</code> column to color the points in the plot.</p>
<div>
<pre><code>iris_aug =<span> </span><span>rowrecs_to_blocks</span>(
  iris,
  controlTable,
  <span>columnsToCopy =</span> <span>&quot;Species&quot;</span>)

<span>head</span>(iris_aug)</code></pre>
</div>
<pre><code>##   Species                  pair_key   x   y
## 1  setosa Sepal.Length Sepal.Length 5.1 5.1
## 2  setosa  Sepal.Width Sepal.Length 3.5 5.1
## 3  setosa Petal.Length Sepal.Length 1.4 5.1
## 4  setosa  Petal.Width Sepal.Length 0.2 5.1
## 5  setosa  Sepal.Length Sepal.Width 5.1 3.5
## 6  setosa   Sepal.Width Sepal.Width 3.5 3.5</code></pre>
<p>Note that the data is now sixteen times larger, which I admit is perverse.</p>
<p>If I didn’t care about how the individual subplots were arranged, I’d be done: I’d plot <code>y</code> vs <code>x</code>, and <code>facet_wrap</code> on <code>pair_key</code>. But I want the subplots arranged in a grid. To do this I use <code>facet_grid</code>, which will require two key columns:</p>
<div>
<pre><code>splt &lt;-<span> </span><span>strsplit</span>(iris_aug$pair_key, <span>split =</span> <span>&quot; &quot;</span>, <span>fixed =</span> <span>TRUE</span>)
iris_aug$xv &lt;-<span> </span><span>vapply</span>(splt, function(si) si[[<span>1</span>]], <span>character</span>(<span>1</span>))
iris_aug$yv &lt;-<span> </span><span>vapply</span>(splt, function(si) si[[<span>2</span>]], <span>character</span>(<span>1</span>))
<span>head</span>(iris_aug)</code></pre>
</div>
<pre><code>##   Species                  pair_key   x   y           xv           yv
## 1  setosa Sepal.Length Sepal.Length 5.1 5.1 Sepal.Length Sepal.Length
## 2  setosa  Sepal.Width Sepal.Length 3.5 5.1  Sepal.Width Sepal.Length
## 3  setosa Petal.Length Sepal.Length 1.4 5.1 Petal.Length Sepal.Length
## 4  setosa  Petal.Width Sepal.Length 0.2 5.1  Petal.Width Sepal.Length
## 5  setosa  Sepal.Length Sepal.Width 5.1 3.5 Sepal.Length  Sepal.Width
## 6  setosa   Sepal.Width Sepal.Width 3.5 3.5  Sepal.Width  Sepal.Width</code></pre>
<p>And now I can produce the graph, using <code>facet_grid</code>.</p>
<div>
<pre><code><span># reorder the key columns to be the same order</span>
<span># as the base version above</span>
iris_aug$xv &lt;-<span> </span><span>factor</span>(<span>as.character</span>(iris_aug$xv),
                           meas_vars)
iris_aug$yv &lt;-<span> </span><span>factor</span>(<span>as.character</span>(iris_aug$yv),
                           meas_vars)


<span>ggplot</span>(iris_aug, <span>aes</span>(<span>x=</span>x, <span>y=</span>y)) +
<span> </span><span>geom_point</span>(<span>aes</span>(<span>color=</span>Species, <span>shape=</span>Species)) +<span> </span>
<span> </span><span>facet_grid</span>(yv~xv, <span>labeller =</span> label_both, <span>scale =</span> <span>&quot;free&quot;</span>) +
<span> </span><span>ggtitle</span>(<span>&quot;Anderson's Iris Data -- 3 species&quot;</span>) +
<span> </span><span>scale_color_brewer</span>(<span>palette =</span> <span>&quot;Dark2&quot;</span>) +
<span> </span><span>ylab</span>(<span>NULL</span>) +<span> </span>
<span> </span><span>xlab</span>(<span>NULL</span>)</code></pre>
</div>
<div>
<p><img border="0" src="https://i0.wp.com/www.win-vector.com/blog/wp-content/uploads/2018/10/unnamed-chunk-8-1.png?resize=660%2C471" alt="Unnamed chunk 8 1" width="450" data-recalc-dims="1"></p>
</div>
<p>This pair plot has <code>x = y</code> plots on the diagonals instead of the names of the variables, but you can confirm that it is otherwise the same as the pair plot produced by <code>pairs()</code>.</p>
<p>Of course, calling <code>pairs()</code> (or <code>ggpairs()</code>, or <code>splom()</code>) is a lot easier than all this, but now I’ve proven to myself that <code>cdata</code> with <code>ggplot2</code> can do the job. This version does have a few advantages. It comes with a legend by default, which is nice. And it’s not obvious how to change the color palette in <code>ggpairs()</code> — I prefer the Brewer Dark2 palette, myself.</p>
<p>Luckily, this code is straightforward to wrap as a function, so if you like the <code>cdata</code> version, I’ve now <a rel="nofollow" href="https://winvector.github.io/WVPlots/reference/PairPlot.html" target="_blank">added the <code>PairPlot()</code> function to <code>WVPlots</code></a>. Now it’s a one-liner, too.</p>
<div>
<pre><code><span>library</span>(WVPlots) 

<span>PairPlot</span>(iris, 
         <span>colnames</span>(iris)[<span>1</span>:<span>4</span>], 
         <span>&quot;Anderson's Iris Data -- 3 species&quot;</span>, 
         <span>group_var =</span> <span>&quot;Species&quot;</span>)</code></pre>
</div>
	<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://www.win-vector.com/blog/2018/10/scatterplot-matrices-pair-plots-with-cdata-and-ggplot2/"> R – Win-Vector Blog</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/RegxBgFurlo" height="1"></a></div>