<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/bland-altman-plot-for-age-comparisons/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://derekogle.com/fishR/2017-04-20-Modified_BlandAltmanPlot"> fishR Blog</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<hr>
<p>Last week I <a target="_blank" rel="nofollow" href="http://derekogle.com/fishR/2017-04-14-Modified_AgeBiasPlot">posted about a modified age bias plot</a>. In this post I began looking more deeply at an alternative plot called the Bland-Altman plot. Below, I describe this plot, demonstrate how to construct it in R, give a mild critique of its use for compare fish age estimates, and develop an alternative that is mean to correct what I see as some of the shortcomings of using the Bland-Altman plot for comparing age estimates. This is large a “thinking out loud” exercise so I am open to any suggestions that you may have.</p>
<h2>Bland-Altman Plot</h2>
<p>The Bland-Altman plot (Bland and Altman 1986) is commonly used in medical and chemistry research to assess agreement between two measurement or assay methods (Giavarina 2015). McBride (2015) used the Bland-Altman plot in his simulation study of the effects of accuracy and precision on the ability to diagnose agreement between sets of fish age estimates. McBride (2015) noted that Bland-Altman plots “<em>readily depict both bias and imprecision</em>” and that this was summarized for “<em>the entire sample, rather than specific age classes.</em>” Despite this, I am aware of only two entries in the fisheries literature that used the Bland-Altman plot to compare fish age estimates (one in the grey literature, one in a thesis). Below, I describe the Bland-Altman plot and then offer a modified version for comparing estimates of fish age.</p>
<p>The Bland-Altman plot is a scatterplot where the differences in two age estimates are on the y-axis and means of the two age estimates are on the x-axis. The plot may be augmented with several horizontal lines at the following locations Figure 1:</p>
<ul>
<li>Zero,</li>
<li>Mean difference in ages (heavy red dashed line),</li>
<li>Upper and lower 95% confidence limits for the mean difference in ages (dark red dashed lines),</li>
<li>Upper and lower 95% “agreement limits” (usually 1.96 times the standard deviation for the difference in ages above and below the mean difference in ages; heavy dashed blue lines), and</li>
<li>Upper and lower 95% confidence limits for the upper and lower “agreement limits” (dashed dark blue lines).</li>
</ul>
<p><img alt="plot of chunk BAEx1" src="https://i2.wp.com/derekogle.com/fishR/figures/BAEx1-1.png?w=456" data-recalc-dims="1"></p>
<p>Figure 1: Bland-Altman plot for comparing scale to otolith age estimates of Lake Champlain Lake Whitefish. Thiw was constructed with <code>BlandAltmanLeh</code>.</p>
<p>As a general rule, a 95% confidence interval for the mean difference that does not contain zero suggests a difference (or a bias) between the two age estimates. For example, a bias is evident in Figure 1. In addition, one would expect 95% of the points to fall within the “agreement limits.” Points that fall outside this range may be considered further as possible outliers. Log differences have been used if the differences are not normally distributed and the percentage difference (where the difference is divided by the mean age) have also been used (Giavarina 2015).</p>
<p>The Bland-Altman plot in Figure 1 was created with <code>bland.altman.plot()</code> from the <code>BlandAltmanLeh</code> package (Lehnert 2015b). Other R functions exist for creating Bland-Altman plots (or the equivalent “Tukey’s Mean Difference Plot”). However, this is a simple plot that can be easily constructed from “scratch” as shown next. I then provide a mild critique of the Bland-Altman plot for use in age comparisons and offer an alternative (that is not an age bias plot).</p>
<h3>Constructing a Bland-Altman Plot</h3>
<p>In this example, a Bland-Altman plot is created to compare consensus (between two readers) scale (<code>scaleC</code>) and otolith (<code>otolithC</code>) age estimates for Lake Champlain Lake Whitefish.</p>
<figure>
<pre><code data-lang="r"><span>library</span><span>(</span><span>FSA</span><span>)</span><span> </span><span># provides WhitefishLC, col2rgbt()
</span><span>data</span><span>(</span><span>WhitefishLC</span><span>)</span><span>
</span><span>str</span><span>(</span><span>WhitefishLC</span><span>)</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## 'data.frame':	151 obs. of  11 variables:
##  $ fishID  : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ tl      : int  345 334 348 300 330 316 508 475 340 173 ...
##  $ scale1  : int  3 4 7 4 3 4 6 4 3 1 ...
##  $ scale2  : int  3 3 5 3 3 4 7 5 3 1 ...
##  $ scaleC  : int  3 4 6 4 3 4 7 5 3 1 ...
##  $ finray1 : int  3 3 3 3 4 2 6 9 2 2 ...
##  $ finray2 : int  3 3 3 2 3 3 6 9 3 1 ...
##  $ finrayC : int  3 3 3 3 4 3 6 9 3 1 ...
##  $ otolith1: int  3 3 3 3 3 6 9 11 3 1 ...
##  $ otolith2: int  3 3 3 3 3 5 10 12 4 1 ...
##  $ otolithC: int  3 3 3 3 3 6 10 11 4 1 ...</code></pre>
</figure>
<p>The mean and differences between the two age estimates are easily computed and added to the original data.frame. One way (of many ways) to do that is with <code>mutate()</code> from <code>dplyr</code> (as shown below).</p>
<figure>
<pre><code data-lang="r"><span>library</span><span>(</span><span>dplyr</span><span>)</span><span>
</span><span>WhitefishLC</span><span> </span><span>&lt;-</span><span> </span><span>mutate</span><span>(</span><span>WhitefishLC</span><span>,</span><span>meanSO</span><span>=</span><span>(</span><span>scaleC</span><span>+</span><span>otolithC</span><span>)</span><span>/</span><span>2</span><span>,</span><span>diffSO</span><span>=</span><span>scaleC</span><span>-</span><span>otolithC</span><span>)</span><span>
</span><span>head</span><span>(</span><span>WhitefishLC</span><span>)</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">##   fishID  tl scale1 scale2 scaleC finray1 finray2 finrayC otolith1
## 1      1 345      3      3      3       3       3       3        3
## 2      2 334      4      3      4       3       3       3        3
## 3      3 348      7      5      6       3       3       3        3
## 4      4 300      4      3      4       3       2       3        3
## 5      5 330      3      3      3       4       3       4        3
## 6      6 316      4      4      4       2       3       3        6
##   otolith2 otolithC meanSO diffSO
## 1        3        3    3.0      0
## 2        3        3    3.5      1
## 3        3        3    4.5      3
## 4        3        3    3.5      1
## 5        3        3    3.0      0
## 6        5        6    5.0     -2</code></pre>
</figure>
<p>A scatterplot is constructed with <code>plot()</code> with a formula of the form <code>y~x</code>. In this case, the points are white (<code>col=&quot;white&quot;</code>) so that the points will not be evident.</p>
<figure>
<pre><code data-lang="r"><span>plot</span><span>(</span><span>diffSO</span><span>~</span><span>meanSO</span><span>,</span><span>data</span><span>=</span><span>WhitefishLC</span><span>,</span><span>col</span><span>=</span><span>&quot;white&quot;</span><span>,</span><span>
</span><span>xlab</span><span>=</span><span>&quot;Mean Age&quot;</span><span>,</span><span>ylab</span><span>=</span><span>&quot;Scale-Otolith Age&quot;</span><span>)</span></code></pre>
</figure>
<p>In this way, items can be added “behind” the points. For example, <code>abline()</code> is used with <code>h=0</code> to add a horizontal reference line at zero.</p>
<figure>
<pre><code data-lang="r"><span>abline</span><span>(</span><span>h</span><span>=</span><span>0</span><span>,</span><span>lwd</span><span>=</span><span>2</span><span>,</span><span>col</span><span>=</span><span>&quot;gray70&quot;</span><span>)</span></code></pre>
</figure>
<p>In addition, horizontal lines at the mean and approximate lower and upper 95% confidence limits for the differences may be added.</p>
<figure>
<pre><code data-lang="r"><span>mndiff</span><span> </span><span>&lt;-</span><span> </span><span>mean</span><span>(</span><span>WhitefishLC</span><span>$</span><span>diffSO</span><span>)</span><span>
</span><span>sediff</span><span> </span><span>&lt;-</span><span> </span><span>se</span><span>(</span><span>WhitefishLC</span><span>$</span><span>diffSO</span><span>)</span><span>
</span><span>abline</span><span>(</span><span>h</span><span>=</span><span>mndiff</span><span>+</span><span>c</span><span>(</span><span>-1.96</span><span>,</span><span>0</span><span>,</span><span>1.96</span><span>)</span><span>*</span><span>sediff</span><span>,</span><span>lty</span><span>=</span><span>2</span><span>,</span><span>col</span><span>=</span><span>&quot;red&quot;</span><span>)</span></code></pre>
</figure>
<p>Agreement lines (without confidence limits) may also be added. [These could, of course, be eliminated to address the second issue below.]</p>
<figure>
<pre><code data-lang="r"><span>sddiff</span><span> </span><span>&lt;-</span><span> </span><span>sd</span><span>(</span><span>WhitefishLC</span><span>$</span><span>diffSO</span><span>)</span><span>
</span><span>abline</span><span>(</span><span>h</span><span>=</span><span>mndiff</span><span>+</span><span>c</span><span>(</span><span>-1.96</span><span>,</span><span>1.96</span><span>)</span><span>*</span><span>sddiff</span><span>,</span><span>lty</span><span>=</span><span>3</span><span>,</span><span>col</span><span>=</span><span>&quot;blue&quot;</span><span>)</span></code></pre>
</figure>
<p>The data points are then added to this base plot with <code>points()</code>. “Solid dots” (<code>pch=19</code>) that are a transparent black such that when five points are overplotted the “point” will appear solid black (<code>col2rgbt(&quot;black&quot;,1/5)</code>) are used to address the first issue below.</p>
<figure>
<pre><code data-lang="r"><span>points</span><span>(</span><span>diffSO</span><span>~</span><span>meanSO</span><span>,</span><span>data</span><span>=</span><span>WhitefishLC</span><span>,</span><span>pch</span><span>=</span><span>19</span><span>,</span><span>col</span><span>=</span><span>col2rgbt</span><span>(</span><span>&quot;black&quot;</span><span>,</span><span>1</span><span>/</span><span>5</span><span>))</span></code></pre>
</figure>
<p><img alt="plot of chunk BAPlotByScratch" src="https://i2.wp.com/derekogle.com/fishR/figures/BAPlotByScratch-1.png?w=456" data-recalc-dims="1"></p>
<p>Figure 2: Bland-Altman plot for comparing scale to otolith age estimates of Lake Champlain Lake Whitefish. Thiw was constructed in parts.</p>
<h3>My Critique of the Bland-Altman Plot for Age Comparisons</h3>
<p>I like that Bland-Altman plots (relative to age bias plots) do not require that one of the variables be designated as the “reference” group. This may be more useful when comparing age estimates where one set of estimates is not clearly <em>a priori</em> considered to be more accurate (e.g., comparing readers with similar levels of experience).</p>
<p>However, I don’t like the following characteristics of (default) Bland-Altman plots.</p>
<ul>
<li>There may be considerable overlap of the plotted points because of the discrete nature of most age data. Various authors have dealt with this by adding a “petal” to the point for each overplotted point to make a so-called “sunflower plot” (Lehnert, 2015a) or using bubbles that are proportional to the number of overplotted points (McBride 2015). However, I find the “sunflowers” and “bubbles” to be distracting. I addressed this issue with transparent points above.</li>
<li>The “agreement lines” are not particularly useful. They may be useful for identifying outliers, but an egregious outlier will likely stand out without these lines.</li>
<li>The single confidence interval for the mean difference suggests that any bias between the sets of estimates is “constant” across the range of mean ages. This can be relaxed somewhat if the percentage difference is plotted on the y-axis. However, neither of these allows for more complex situations where the bias is nonlinear with age. For example, a common situation of little difference between the estimates at young ages, but increasing differences with increasing ages (e.g., Figure 1) is not well-represented by this single confidence interval.</li>
</ul>
<h3>A Modified Bland-Altman Plot for Age Comparisons</h3>
<p>The third issue above has been addressed with some Bland-Altman plots by fitting a linear regression that describes the difference in age estimates as a function of mean age (Giarvina 2015). However, this only allows for a linear relationship, which may not represent or reveal more interesting nonlinear relationships. A generalized additive model (GAM) could be used to estimate a “smoothed” potentially nonlinear relationship between the differences in ages and the means of the ages.</p>
<p>A GAM may be fit in R with <code>gam()</code> from the <code>mgcv</code> package (Wood 2006). A thin-plate regression spline (Wood 2003) is used as the smoother by default when <code>s()</code> is used on the right-hand-side of the formula in <code>gam()</code>. The degree of smoothing is controlled by <code>k=</code> in <code>s()</code>. I have found (with minimal experience) that <code>k=5</code> may be adequate for most age comparison situations (note that smaller values provide more smoothing, larger values provide less smoothing).</p>
<figure>
<pre><code data-lang="r"><span>library</span><span>(</span><span>mgcv</span><span>)</span><span>
</span><span>mod1</span><span> </span><span>&lt;-</span><span> </span><span>gam</span><span>(</span><span>diffSO</span><span>~</span><span>s</span><span>(</span><span>meanSO</span><span>,</span><span>k</span><span>=</span><span>5</span><span>),</span><span>data</span><span>=</span><span>WhitefishLC</span><span>)</span></code></pre>
</figure>
<p>Summary of the model fit is seen by submitting the <code>gam</code> object to <code>summary()</code>. In this example, the approximate p-value for the smoother term suggests that there is a relationship between the differences and means.</p>
<figure>
<pre><code data-lang="r"><span>summary</span><span>(</span><span>mod1</span><span>)</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">## 
## Family: gaussian 
## Link function: identity 
## 
## Formula:
## diffSO ~ s(meanSO, k = 5)
## 
## Parametric coefficients:
##             Estimate Std. Error t value Pr(>|t|)
## (Intercept)  -1.7815     0.1525  -11.68   &lt;2e-16
## 
## Approximate significance of smooth terms:
##             edf Ref.df     F p-value
## s(meanSO) 3.438  3.827 33.53  &lt;2e-16
## 
## R-sq.(adj) =  0.461   Deviance explained = 47.4%
## GCV =  3.617  Scale est. = 3.5107    n = 151</code></pre>
</figure>
<p>The smoother “line” with 95% confidence limits is added to the plot by first using the smoother to predict the differences in ages (along with the SE of those predictions) across the entire range of mean ages. Approximate confidence limits are then derived (using normal theory) from the predicted values and their SEs.</p>
<figure>
<pre><code data-lang="r"><span>tmp</span><span> </span><span>&lt;-</span><span> </span><span>seq</span><span>(</span><span>0</span><span>,</span><span>18</span><span>,</span><span>0.1</span><span>)</span><span>
</span><span>pred1</span><span> </span><span>&lt;-</span><span> </span><span>data.frame</span><span>(</span><span>age</span><span>=</span><span>tmp</span><span>,</span><span>
</span><span>predict</span><span>(</span><span>mod1</span><span>,</span><span>data.frame</span><span>(</span><span>meanSO</span><span>=</span><span>tmp</span><span>),</span><span>type</span><span>=</span><span>&quot;response&quot;</span><span>,</span><span>se</span><span>=</span><span>TRUE</span><span>))</span><span> </span><span>%>%</span><span>
</span><span>mutate</span><span>(</span><span>LCI</span><span>=</span><span>fit</span><span>-1.96</span><span>*</span><span>se.fit</span><span>,</span><span>UCI</span><span>=</span><span>fit</span><span>+1.96</span><span>*</span><span>se.fit</span><span>)</span><span>
</span><span>head</span><span>(</span><span>pred1</span><span>)</span></code></pre>
</figure>
<figure>
<pre><code data-lang="text">##   age        fit    se.fit       LCI      UCI
## 1 0.0 -0.2479616 0.7058686 -1.631464 1.135541
## 2 0.1 -0.2333355 0.6846088 -1.575169 1.108498
## 3 0.2 -0.2187095 0.6634582 -1.519088 1.081669
## 4 0.3 -0.2040835 0.6424276 -1.463241 1.055075
## 5 0.4 -0.1894574 0.6215291 -1.407654 1.028740
## 6 0.5 -0.1748314 0.6007766 -1.352354 1.002691</code></pre>
</figure>
<p>The smoother “line” is then added to the plot with <code>lines()</code>.</p>
<figure>
<pre><code data-lang="r"><span>lines</span><span>(</span><span>fit</span><span>~</span><span>age</span><span>,</span><span>data</span><span>=</span><span>pred1</span><span>,</span><span>lwd</span><span>=</span><span>2</span><span>,</span><span>lty</span><span>=</span><span>2</span><span>,</span><span>col</span><span>=</span><span>&quot;red&quot;</span><span>)</span></code></pre>
</figure>
<p>The 95% intervals for the smoother line are added as lines with <code>lines()</code></p>
<figure>
<pre><code data-lang="r"><span>lines</span><span>(</span><span>LCI</span><span>~</span><span>age</span><span>,</span><span>data</span><span>=</span><span>pred1</span><span>,</span><span>lty</span><span>=</span><span>3</span><span>,</span><span>col</span><span>=</span><span>&quot;red&quot;</span><span>)</span><span>
</span><span>lines</span><span>(</span><span>UCI</span><span>~</span><span>age</span><span>,</span><span>data</span><span>=</span><span>pred1</span><span>,</span><span>lty</span><span>=</span><span>3</span><span>,</span><span>col</span><span>=</span><span>&quot;red&quot;</span><span>)</span></code></pre>
</figure>
<p>Alternatively, the 95% intervals for the smoother line may be added as a shaded region with <code>polygon()</code>. Note that <code>rev()</code> reverses the order of the elements in a vector and is a “trick” used to properly construct the boundaries of the polygon for plotting.</p>
<figure>
<pre><code data-lang="r"><span>with</span><span>(</span><span>pred1</span><span>,</span><span>polygon</span><span>(</span><span>c</span><span>(</span><span>age</span><span>,</span><span>rev</span><span>(</span><span>age</span><span>)),</span><span>c</span><span>(</span><span>LCI</span><span>,</span><span>rev</span><span>(</span><span>UCI</span><span>)),</span><span>
</span><span>border</span><span>=</span><span>NA</span><span>,</span><span>col</span><span>=</span><span>col2rgbt</span><span>(</span><span>&quot;red&quot;</span><span>,</span><span>1</span><span>/</span><span>10</span><span>)))</span></code></pre>
</figure>
<p>Putting this all together results in the plot shown in Figure 3. These results suggest that there is little difference between scale and otolith age estimates up to a mean age estimate of approximately five, after which age estimates from scales are less than age estimates from otoliths, with the difference between the two generally increasing with increasing mean age.</p>
<figure>
<pre><code data-lang="r"><span>plot</span><span>(</span><span>diffSO</span><span>~</span><span>meanSO</span><span>,</span><span>data</span><span>=</span><span>WhitefishLC</span><span>,</span><span>col</span><span>=</span><span>&quot;white&quot;</span><span>,</span><span>
</span><span>xlab</span><span>=</span><span>&quot;Mean Age&quot;</span><span>,</span><span>ylab</span><span>=</span><span>&quot;Scale-Otolith Age&quot;</span><span>)</span><span>
</span><span>abline</span><span>(</span><span>h</span><span>=</span><span>0</span><span>,</span><span>lwd</span><span>=</span><span>2</span><span>,</span><span>col</span><span>=</span><span>&quot;gray70&quot;</span><span>)</span><span>
</span><span>lines</span><span>(</span><span>fit</span><span>~</span><span>age</span><span>,</span><span>data</span><span>=</span><span>pred1</span><span>,</span><span>lwd</span><span>=</span><span>2</span><span>,</span><span>lty</span><span>=</span><span>2</span><span>,</span><span>col</span><span>=</span><span>&quot;red&quot;</span><span>)</span><span>
</span><span>with</span><span>(</span><span>pred1</span><span>,</span><span>polygon</span><span>(</span><span>c</span><span>(</span><span>age</span><span>,</span><span>rev</span><span>(</span><span>age</span><span>)),</span><span>c</span><span>(</span><span>LCI</span><span>,</span><span>rev</span><span>(</span><span>UCI</span><span>)),</span><span>
</span><span>border</span><span>=</span><span>NA</span><span>,</span><span>col</span><span>=</span><span>col2rgbt</span><span>(</span><span>&quot;red&quot;</span><span>,</span><span>1</span><span>/</span><span>10</span><span>)))</span><span>
</span><span>points</span><span>(</span><span>diffSO</span><span>~</span><span>meanSO</span><span>,</span><span>data</span><span>=</span><span>WhitefishLC</span><span>,</span><span>pch</span><span>=</span><span>19</span><span>,</span><span>col</span><span>=</span><span>col2rgbt</span><span>(</span><span>&quot;black&quot;</span><span>,</span><span>1</span><span>/</span><span>5</span><span>))</span></code></pre>
</figure>
<p><img alt="plot of chunk MBAEx1" src="https://i2.wp.com/derekogle.com/fishR/figures/MBAEx1-1.png?w=456" data-recalc-dims="1"></p>
<p>Figure 3: Scatterplot of the difference in scale and otolith age estimates versus the mean of the scale and otolith age estimates of Lake Champlain Lake Whitefish with a thin-plate regression spline smoother and 95% confidence band shown.</p>
<p>A similar plot is shown for the comparison of otolith age estimates between two readers in Figure 4. Also note (see below) that the smoother term is not significant for the between-reader comparison of otolith age estimates, which suggests no relationship between the differences in ages and the mean age. In addition, the intercept term is not significantly different from zero, which indicates that there is not a constant bias between the two readers.</p>
<figure>
<pre><code data-lang="text">## 
## Family: gaussian 
## Link function: identity 
## 
## Formula:
## diffOO ~ s(meanOO, k = 5)
## 
## Parametric coefficients:
##             Estimate Std. Error t value Pr(>|t|)
## (Intercept)   0.0000     0.0611       0        1
## 
## Approximate significance of smooth terms:
##           edf Ref.df     F p-value
## s(meanOO)   1      1 0.013   0.909
## 
## R-sq.(adj) =  -0.00662   Deviance explained = 0.00881%
## GCV = 0.57128  Scale est. = 0.56371   n = 151</code></pre>
</figure>
<p><img alt="plot of chunk MBAEx2" src="https://i2.wp.com/derekogle.com/fishR/figures/MBAEx2-1.png?w=456" data-recalc-dims="1"></p>
<p>Figure 4: Scatterplot of the difference between otolith age estimates for two readers and the mean otolith age estimates of Lake Champlain Lake Whitefish with a thin-plate regression spline smoother and 95% confidence band shown.</p>
<h3>Adding the GAM to the Age Bias Plot</h3>
<p>In situations where one of the age estimates could be considered <em>a priori</em> to be more accurate, it seems to make more sense to put that age estimate on the x-axis rather than the mean between it and the less accurate estimate. In other words, return to the concept, though not the exact structure, of the age bias plot. The GAM smoother can also be added to this plot (Figures 5 and 6).</p>
<figure>
<pre><code data-lang="r"><span>mod1a</span><span> </span><span>&lt;-</span><span> </span><span>gam</span><span>(</span><span>diffSO</span><span>~</span><span>s</span><span>(</span><span>otolithC</span><span>,</span><span>k</span><span>=</span><span>15</span><span>),</span><span>data</span><span>=</span><span>WhitefishLC</span><span>)</span><span>
</span><span>plot</span><span>(</span><span>diffSO</span><span>~</span><span>otolithC</span><span>,</span><span>data</span><span>=</span><span>WhitefishLC</span><span>,</span><span>col</span><span>=</span><span>&quot;white&quot;</span><span>,</span><span>
</span><span>xlab</span><span>=</span><span>&quot;Otolith Age&quot;</span><span>,</span><span>ylab</span><span>=</span><span>&quot;Scale - Otolith Age&quot;</span><span>)</span><span>
</span><span>abline</span><span>(</span><span>h</span><span>=</span><span>0</span><span>,</span><span>lwd</span><span>=</span><span>2</span><span>,</span><span>col</span><span>=</span><span>&quot;gray70&quot;</span><span>)</span><span>
</span><span>tmp</span><span> </span><span>&lt;-</span><span> </span><span>seq</span><span>(</span><span>0</span><span>,</span><span>25</span><span>,</span><span>0.1</span><span>)</span><span>
</span><span>pred1a</span><span> </span><span>&lt;-</span><span> </span><span>data.frame</span><span>(</span><span>age</span><span>=</span><span>tmp</span><span>,</span><span>
</span><span>predict</span><span>(</span><span>mod1a</span><span>,</span><span>data.frame</span><span>(</span><span>otolithC</span><span>=</span><span>tmp</span><span>),</span><span>type</span><span>=</span><span>&quot;response&quot;</span><span>,</span><span>se</span><span>=</span><span>TRUE</span><span>))</span><span> </span><span>%>%</span><span>
</span><span>mutate</span><span>(</span><span>LCI</span><span>=</span><span>fit</span><span>-1.96</span><span>*</span><span>se.fit</span><span>,</span><span>UCI</span><span>=</span><span>fit</span><span>+1.96</span><span>*</span><span>se.fit</span><span>)</span><span>
</span><span>lines</span><span>(</span><span>fit</span><span>~</span><span>age</span><span>,</span><span>data</span><span>=</span><span>pred1a</span><span>,</span><span>lwd</span><span>=</span><span>2</span><span>,</span><span>lty</span><span>=</span><span>2</span><span>,</span><span>col</span><span>=</span><span>&quot;red&quot;</span><span>)</span><span>
</span><span>with</span><span>(</span><span>pred1a</span><span>,</span><span>polygon</span><span>(</span><span>c</span><span>(</span><span>age</span><span>,</span><span>rev</span><span>(</span><span>age</span><span>)),</span><span>c</span><span>(</span><span>LCI</span><span>,</span><span>rev</span><span>(</span><span>UCI</span><span>)),</span><span>
</span><span>border</span><span>=</span><span>NA</span><span>,</span><span>col</span><span>=</span><span>col2rgbt</span><span>(</span><span>&quot;red&quot;</span><span>,</span><span>1</span><span>/</span><span>10</span><span>)))</span><span>
</span><span>points</span><span>(</span><span>diffSO</span><span>~</span><span>otolithC</span><span>,</span><span>data</span><span>=</span><span>WhitefishLC</span><span>,</span><span>pch</span><span>=</span><span>19</span><span>,</span><span>col</span><span>=</span><span>col2rgbt</span><span>(</span><span>&quot;black&quot;</span><span>,</span><span>1</span><span>/</span><span>5</span><span>))</span></code></pre>
</figure>
<p><img alt="plot of chunk MBAExAB1" src="https://i1.wp.com/derekogle.com/fishR/figures/MBAExAB1-1.png?w=456" data-recalc-dims="1"></p>
<p>Figure 5: Scatterplot of the difference in scale and otolith age estimates versus otolith age estimates of Lake Champlain Lake Whitefish with a thin-plate regression spline smoother and 95% confidence band shown.</p>
<p><img alt="plot of chunk MBAExAB2" src="https://i0.wp.com/derekogle.com/fishR/figures/MBAExAB2-1.png?w=456" data-recalc-dims="1"></p>
<p>Figure 6: Scatterplot of the difference otolith age estimates for two readers and the otolith age estimates for the first reader of Lake Champlain Lake Whitefish with a thin-plate regression spline smoother and 95% confidence band shown.</p>
<h3>Things To Do</h3>
<p>If this all seems plausible then consider:</p>
<ul>
<li>Add histogram to right-side (show distribution of differences).</li>
<li>Perhaps run McBride’s simulations through this.</li>
</ul>
<hr>
<h3>References</h3>
<ul>
<li>
<p>Bland, J.M., and D.G. Altman. 1986. <a target="_blank" rel="nofollow" href="https://www-users.york.ac.uk/~mb55/meas/ba.pdf">Statistical methods for assessing agreement between two methods of clinical measurement.</a> Lancet i:307-317.</p>
</li>
<li>
<p>Giarvina, D. 2015. <a target="_blank" rel="nofollow" href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4470095/">Understanding Bland Altman analysis.</a> Biochemica Medica 24:141-151.</p>
</li>
<li>
<p>Lehnert, B. 2015a. <a target="_blank" rel="nofollow" href="https://cran.r-project.org/web/packages/BlandAltmanLeh/vignettes/Intro.html">BlandAltmanLeh Intro</a>. Accessed on 18-Apr-17.</p>
</li>
<li>
<p>Lehnert, B. 2015b. <a target="_blank" rel="nofollow" href="https://cran.r-project.org/package=BlandAltmanLeh">BlandAltmanLeh: Plots (Slightly Extended) Bland-Altman Plots.</a> R package version 0.3.1.</p>
</li>
<li>
<p>McBride, R.S. 2015. <a target="_blank" rel="nofollow" href="https://academic.oup.com/icesjms/article/72/7/2149/2457853/Diagnosis-of-paired-age-agreement-a-simulation-of">Diagnois of paired age agreement: a simulation of accuracy and precision effects.</a> ICES Journal of Marine Science 72:2149-2167.</p>
</li>
<li>
<p>Wood, S.N. 2003. Thin-plate regression splines. Journal of the Royal Statistical Society (B)<br>
65(1):95-114.</p>
</li>
<li>
<p>Wood, S.N. 2006. Generalized Additive Models: An Introduction with R. Chapman and Hall/CRC.</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-20-Modified_BlandAltmanPlot"> 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/spmh5BmIlIk"></a></div>