<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/modified-age-bias-plot/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://derekogle.com/fishR/2017-04-14-Modified_AgeBiasPlot"> fishR Blog</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<hr>
<h2>Original Age Bias Plot</h2>
<p>Campana <em>et al.</em> (1995) introduced the “age bias plot” to visually assess potential differences in paired age estimates (e.g., between two structures such as scales and otoliths, between two readers, or between one reader at two times). One set of age estimates serve as “reference” ages in the age bias plot. The reference ages are usually the age estimates thought to be most accurate (i.e., the most accurate structure, “best” reader), but could be from the first reading if two readings from the same reader are made. The reference estimates form the x-axis on the age-bias plot. The mean and 95% confidence interval for the nonreference age estimates computed at each value of the reference age estimates are plotted to form the age bias plot. A 1:1 line that represents agreement between the two age estimates is usually included. Confidence intervals that do not capture this “agreement line” suggest a difference in the two age estimates at that reference age. An example age bias plot is below.</p>
<p><img alt="plot of chunk ABCampana" src="https://i0.wp.com/derekogle.com/fishR/figures/ABCampana-1.png?w=456" data-recalc-dims="1"></p>
<p>The age bias plot above was constructed with the code below. Briefly, the foundational calculations for the age bias plot are constructed with <code>ageBias()</code>, where the variable with the reference age estimates follows the tilde. The age bias plot is then constructed by submitting the <code>ageBias()</code> results to <code>plot()</code>. The <code>col.CIsig=</code>, <code>pch.mean.sig=</code>, <code>sfrac=</code>, <code>lty.agree=</code>, and <code>col.agree=</code> arguments are used here to modify default settings for these arguments so that the resultant age bias plot most closely resembles that described by Campana <em>et al.</em> (1995). These arguments are discussed further in the next section.</p>
<figure>
<pre><code data-lang="r"><span>library</span><span>(</span><span>FSA</span><span>)</span><span> </span><span># provides ageBias(), plot() and WhitefishLC
</span><span>data</span><span>(</span><span>WhitefishLC</span><span>)</span><span> </span><span># example data
</span><span>ab1</span><span> </span><span>&lt;-</span><span> </span><span>ageBias</span><span>(</span><span>scaleC</span><span>~</span><span>otolithC</span><span>,</span><span>data</span><span>=</span><span>WhitefishLC</span><span>,</span><span>
</span><span>nref.lab</span><span>=</span><span>&quot;Scale Age&quot;</span><span>,</span><span>ref.lab</span><span>=</span><span>&quot;Otolith Age&quot;</span><span>)</span><span>
</span><span>plot</span><span>(</span><span>ab1</span><span>,</span><span>col.CIsig</span><span>=</span><span>&quot;black&quot;</span><span>,</span><span>pch.mean.sig</span><span>=</span><span>19</span><span>,</span><span>sfrac</span><span>=</span><span>0.01</span><span>,</span><span>
</span><span>lty.agree</span><span>=</span><span>1</span><span>,</span><span>col.agree</span><span>=</span><span>&quot;black&quot;</span><span>)</span></code></pre>
</figure>
<h2>Making a “Cleaner” Age Bias Plot</h2>
<p>I found the age bias plot to be useful for detecting systematic differences in estimated ages between two sets of readings, but I also found the plot to be “clunky” with some data sets. Thus, I modified the original design in several ways. The first set of changes were simply to make the plot “cleaner” and easier to interpret. Specific changes I made are described below.</p>
<ul>
<li>Used a 1-sample t-test to determine if mean nonreference age (i.e., y-axis) differed significantly from the reference age for each reference age (i.e., x-axis). In other words, for example, does the mean nonreference age at a reference age of 3 differ from 3? This test was repeated for each reference age and the resultant p-values were corrected for multiple comparisons. Reference ages for which a significant difference was detected were plotted by default with an open symbol and a different color. The symbol and color for the ages where a significant difference was detected are controlled by <code>col.CIsig=</code> and <code>pch.mean.sig=</code>, respectively.</li>
<li>Confidence intervals for reference ages with small sample sizes can be very wide, which can cause poor scaling of the y-axis on the age bias plot. The <code>min.n.CI=</code> argument in <code>ageBias()</code> sets a sample size threshold for when confidence intervals are constructed. The default for this argument is 3 (i.e., a confidence interval will be constructed if the sample size is at least 3).</li>
<li>Made the agreement line a ligher gray and dashed so that it can be seen but it is less bold. The type and color of the agreement line are controlled by <code>lty.agree=</code> and <code>col.agree=</code>, respectively.</li>
<li>Removed the “caps” on the ends of the confidence intervals to reduce clutter. The length of the confidence interval ends are controlled by <code>sfrac=</code>.</li>
</ul>
<p>These modifications are the defaults settings in <code>ageBias()</code> and <code>plot()</code>.</p>
<figure>
<pre><code data-lang="r"><span>plot</span><span>(</span><span>ab1</span><span>)</span></code></pre>
</figure>
<p><img alt="plot of chunk ABCampanaClean" src="https://i1.wp.com/derekogle.com/fishR/figures/ABCampanaClean-1.png?w=456" data-recalc-dims="1"></p>
<h2>Plotting Differences on the Y-Axis</h2>
<p>Muir <em>et al.</em> (2008) were the first (to my knowledge) to modify the age bias plot by using the difference between the reference ages and the mean nonreference ages on the y-axis. I modified this concept by first computing the difference between the nonreference and reference ages (nonreference-reference) for each individual and then computing the mean of those differences for each reference age. With this modification, the mean difference between nonreference and reference ages is plotted against the reference ages. The “agreement line” is now a horizontal line at 0 on this plot. This modified age bias plot is constructed by including <code>difference=TRUE</code> in <code>ageBias()</code>.</p>
<figure>
<pre><code data-lang="r"><span>plot</span><span>(</span><span>ab1</span><span>,</span><span>difference</span><span>=</span><span>TRUE</span><span>)</span></code></pre>
</figure>
<p><img alt="plot of chunk ABDifferences1" src="https://i1.wp.com/derekogle.com/fishR/figures/ABDifferences1-1.png?w=456" data-recalc-dims="1"></p>
<h2>Showing Individual Variability</h2>
<p>I often wanted to have a feel for the individual variabilty underlying the age bias plot. A faint gray line “behind” that stretches from the minimum to the maximum nonreference age for each reference age is plotted behind each confidence interval by including <code>show.range=TRUE</code>.</p>
<figure>
<pre><code data-lang="r"><span>plot</span><span>(</span><span>ab1</span><span>,</span><span>difference</span><span>=</span><span>TRUE</span><span>,</span><span>show.range</span><span>=</span><span>TRUE</span><span>)</span></code></pre>
</figure>
<p><img alt="plot of chunk ABShowRange" src="https://i2.wp.com/derekogle.com/fishR/figures/ABShowRange-1.png?w=456" data-recalc-dims="1"></p>
<p>Alternatively, individual points (for paired age estimates) are included with <code>show.pts=TRUE</code>. There tends to be considerable overplotting of individual points because of the discrete nature of age data. To make individual points more obvious, a transparent color can be used for each point such that more overlapping points will appear darker. The level of transparency is controlled by including an integer in <code>transparency=</code>, with values further from 1 being more transparent.</p>
<figure>
<pre><code data-lang="r"><span>plot</span><span>(</span><span>ab1</span><span>,</span><span>difference</span><span>=</span><span>TRUE</span><span>,</span><span>show.pts</span><span>=</span><span>TRUE</span><span>)</span></code></pre>
</figure>
<p><img alt="plot of chunk ABShowPoints" src="https://i1.wp.com/derekogle.com/fishR/figures/ABShowPoints-1.png?w=456" data-recalc-dims="1"></p>
<h2>Illustrating Sample Size</h2>
<p>I also often want to know the sample sizes underlying the age bias plot. In particular, it is useful to know the number of nonreference age estimates that contributed to each mean and confidence interval. My first attempt at providing this information on the plot was to simply print the values on the plot (usually above the plot or just above the x-axis). The sample sizee can be added to the plot with <code>show.n=TRUE</code>.</p>
<figure>
<pre><code data-lang="r"><span>plot</span><span>(</span><span>ab1</span><span>,</span><span>difference</span><span>=</span><span>TRUE</span><span>,</span><span>show.n</span><span>=</span><span>TRUE</span><span>)</span></code></pre>
</figure>
<p><img alt="plot of chunk ABShowN" src="https://i1.wp.com/derekogle.com/fishR/figures/ABShowN-1.png?w=456" data-recalc-dims="1"></p>
<p>These values, however, are often either so crowded or so small as to be of little utility. Recently I added the ability to add marginal histograms to the age bias plot. For example, a histogram of the sample sizes in the previous plot can be added by using <code>xHist=TRUE</code>.</p>
<figure>
<pre><code data-lang="r"><span>plot</span><span>(</span><span>ab1</span><span>,</span><span>difference</span><span>=</span><span>TRUE</span><span>,</span><span>xHist</span><span>=</span><span>TRUE</span><span>)</span></code></pre>
</figure>
<p><img alt="plot of chunk ABHistX" src="https://i2.wp.com/derekogle.com/fishR/figures/ABHistX-1.png?w=456" data-recalc-dims="1"></p>
<p>The same can be added for the nonreference ages with <code>yHist=TRUE</code>. This plot has the added advantage of showing the distribution of differences in age estimates, with the bar at a difference of zero representing the amount of perfect agreement between the sets of age estimates.</p>
<figure>
<pre><code data-lang="r"><span>plot</span><span>(</span><span>ab1</span><span>,</span><span>difference</span><span>=</span><span>TRUE</span><span>,</span><span>xHist</span><span>=</span><span>TRUE</span><span>,</span><span>yHist</span><span>=</span><span>TRUE</span><span>)</span></code></pre>
</figure>
<p><img alt="plot of chunk ABHistXY" src="https://i2.wp.com/derekogle.com/fishR/figures/ABHistXY-1.png?w=456" data-recalc-dims="1"></p>
<p>The same plot, but with a marginal histogram of the nonreference age estimates rather than the difference in age estimates is also nice for showing the age distributions for both sets of age estimates.</p>
<figure>
<pre><code data-lang="r"><span>plot</span><span>(</span><span>ab1</span><span>,</span><span>xHist</span><span>=</span><span>TRUE</span><span>,</span><span>yHist</span><span>=</span><span>TRUE</span><span>)</span></code></pre>
</figure>
<p><img alt="plot of chunk ABDiffHistXY" src="https://i1.wp.com/derekogle.com/fishR/figures/ABDiffHistXY-1.png?w=456" data-recalc-dims="1"></p>
<h2>My Preference</h2>
<p>My current preference for an age bias plot is to use the differences in age estimates, plot both marginal histograms (I like to see the distributions for the reference age estimates and the difference in age estimates), to show the individual points, and to remove the coloring for significantly different ages (though, I like the difference in symbols). An example of my preferred plot is shown below for ages estimated from fin rays for two readers.</p>
<figure>
<pre><code data-lang="r"><span>abOO</span><span> </span><span>&lt;-</span><span> </span><span>ageBias</span><span>(</span><span>finray2</span><span>~</span><span>finray1</span><span>,</span><span>data</span><span>=</span><span>WhitefishLC</span><span>,</span><span>
</span><span>nref.lab</span><span>=</span><span>&quot;Reader 2 Age&quot;</span><span>,</span><span>ref.lab</span><span>=</span><span>&quot;Reader 1 Age&quot;</span><span>)</span><span> </span><span>plot</span><span>(</span><span>abOO</span><span>,</span><span>difference</span><span>=</span><span>TRUE</span><span>,</span><span>xHist</span><span>=</span><span>TRUE</span><span>,</span><span>yHist</span><span>=</span><span>TRUE</span><span>,</span><span>
</span><span>col.CIsig</span><span>=</span><span>&quot;black&quot;</span><span>,</span><span>show.pts</span><span>=</span><span>TRUE</span><span>)</span></code></pre>
</figure>
<p><img alt="plot of chunk ABPreferred" src="https://i0.wp.com/derekogle.com/fishR/figures/ABPreferred-1.png?w=456" data-recalc-dims="1"></p>
<h2>A Couple of Details</h2>
<p>The modifications of the age bias plot described here are available in the <a target="_blank" rel="nofollow" href="https://github.com/droglenc/FSA#installation">development version of the FSA package</a>, but not yet in the stable CRAN version. They will appear in v0.8.13.</p>
<p>Several of the options illustrated above can be modified with other arguments to <code>ageBias()</code>. See the documentation for further details (i.e., use <code>?ageBias</code>).</p>
<p>The plots in this post used the following modifications of the default base graphing parameters. These changes make narrower margins around the plot, move the axis labels closer to the axes, and reduce the size of the axis tick marks relative to the default values.</p>
<figure>
<pre><code data-lang="r"><span>par</span><span>(</span><span>mar</span><span>=</span><span>c</span><span>(</span><span>3.5</span><span>,</span><span>3.5</span><span>,</span><span>1</span><span>,</span><span>1</span><span>),</span><span>mgp</span><span>=</span><span>c</span><span>(</span><span>2.1</span><span>,</span><span>0.4</span><span>,</span><span>0</span><span>),</span><span>tcl</span><span>=</span><span>-0.2</span><span>)</span></code></pre>
</figure>
<h2>Final Thoughts</h2>
<p>Please let me know what you think about my preferred age bias plot. In general, I like it and feel that it is more informative than other age bias plots. However, I am not quite satisfied with how I separated the “axes” labels for the main age bias plot and the marginal histograms. It looks “hacky” to me.</p>
<p>In addition, I thought about putting a horizontal line on the top marginal histogram that shows the cutoff for when a confidence interval is calculated. I also thought about highlighting the “zero bar” in the right marginal histogram when <code>difference=TRUE</code> to further highlight the amount of agreement between the age estimates. In the end, I did not make these modifications because they would seem to add clutter or draw too much attention.</p>
<p>Let me know if you have other ideas for how these age bias plots could be modified to be more informative.</p>
<hr>
<h3>References</h3>
<ul>
<li>
<p>Campana, S.E., M.C. Annand, and J.I. McMillan. 1995. <a target="_blank" rel="nofollow" href="https://www.researchgate.net/profile/Steven_Campana/publication/254328508_Graphical_and_Statistical_Methods_for_Determining_the_Consistency_of_Age_Determinations/links/546a55d20cf20dedafd386b5.pdf">Graphical and statistical methods for determining the consistency of age determinations.</a> Transactions of the American Fisheries Society 124:131-138.</p>
</li>
<li>
<p>Muir, A.M., M.P. Ebener, J.X. He, and J.E. Johnson. 2008. <a target="_blank" rel="nofollow" href="http://www.tandfonline.com/doi/abs/10.1577/M06-160.1">A comparison of the scale and otolith methods of age estimation for lake whitefish in Lake Huron.</a> North American Journal of Fisheries Management 28:625-635.</p>
</li>
<li>
<p>Ogle, D.H. 2015. <a target="_blank" rel="nofollow" href="http://derekogle.com/IFAR/">Introductory Fisheries Analyses with R book</a>. CRC Press.</p>
</li>
</ul>
<hr>
<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://derekogle.com/fishR/2017-04-14-Modified_AgeBiasPlot"> fishR 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 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/search/tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/search/data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/search/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/search/ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/search/map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/search/animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/search/sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/search/SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/search/git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/search/hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/search/PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/search/time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/search/trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/owrUB9YlPFg"></a></div>