Introduction
The compSlopes()
function in FSA
(prior to v0.9.0) was used to statistically compare slopes for all pairs of groups in an indicator/dummy variable regression (I/DVR). However, the excellent emtrends()
function in the emmmeans
package is a more general and strongly principaled function for this purpose. As such, compSlopes()
will be removed from the next version (0.9.0) of FSA
.
In this post I demonstrate how to use emtrends()
for the same purpose as compSlopes()
was used (prior to FSA v0.9.0). Note, however, that the results will not be identical because compSlopes()
and emtrends()
use different methods to correct for multiple comparisons when comparing pairs of slopes.
The Mirex
data described here, but filtered to include just three years, will be used in this post.^{1}
The lm()
below fits the I/DVR to determine if the relationship between mirex concentration and weight of the salmon differs by year.
The weight:year
interaction term pvalue suggests that the slopes (i.e., relationship between mirex concentration and salmon weight) differs among some pair(s) of the three years.
A next step is to determine which pair(s) of slopes differ significantly.
compSlopes()
from FSA
The procedure coded in compSlopes()
is described in more detail in this supplement to the Introductory Fisheries Analyses with R book. The results of compSlopes()
applied to the saved lm()
object are assigned to an object below.^{2}
The $comparisons
component in this saved object contains the results from comparing all pairs of slopes. Each paired comparison is a row in these results with the groups being compared under comparison
, the differences in sample slopes under diff
, 95% confidence intervals for the difference in slopes under 95% LCI
and 95% UCI
, and unadjusted and adjusted (for multiple comparisons) pvalues for the hypothesis test comparing the slopes under p.unadj
and p.adj
, respectively.
For example, these results suggest that the slopes for 1996 and 1992 ARE statistically different (first row), but the slopes for 1999 and 1996 are NOT statistically different (last row).
The $slope
component in this saved object contains results specific to each slope. The groups are under level
, sample slopes under slopes
, 95% confidence intervals for the slopes under 95% LCI
and 95% UCI
, and unadjusted and adjusted pvalues for the test if the slope is different from 0 under p.unadj
and p.adj
, respectively.
For example, the slope for 1992 (last row) appears to be significantly different than 0 and may be between 0.01679 and 0.03628.
emtrends()
from emmeans
Similar results can be obtained with emtrends()
from emmeans
using the fitted lm()
object as the first argument, a specs=
argument with pairwise~
followed by the name of the factor variable from the lm()
model (year
in this case), and var=
followed by the name of the covariate from the lm()
model (weight
in this case), which must be in quotes.
The object saved from emtrends()
is then given as the first argument to summary()
, which also requires infer=TRUE
if you would like pvalues to be calculated.^{3}
The $contrasts
component in this saved object contains the results for comparing all pairs of slopes. Each paired comparison is a row with the groups compared under contrasts
, the difference in sample slopes under diff
, the standard error of the difference in sample slopes under SE
, the degreesoffreedom under df
, a 95% confidence interval for the difference in slopes under lower.CL
and upper.CL
, and the t test statistic and pvalue adjusted for multiple comparisons for testing a difference in slopes under t.ratio
and p.value
, respectively.
Comparing these results to the $comparison
component from compSlopes()
shows that the difference in sample slopes are the same, but that the confidence interval values and pvalues are slightly different. Again, this is due to emtrends()
and compSlopes()
using different methods of adjusting for multiple comparisons. These differences did not result in different conclusions in this case, but they could, especially if the pvalues are near the rejection criterion.
The $emtrends
component contains results for each slope with the groups under the name of the factor variable (year
in this example), the sample slopes under xxx.trend
(where xxx
is replaced with the name of the covariate variable, weight
in this example), standard errors of the sample slopes under SE
, degreesoffreedom under df
, 95% confidence intervals for the slope under lower.CL
and upper.CL
, and t test statistics and pvalues adjusted for multiple comparisons for testing that the slope is not equal to zero under t.ratio
and p.adj
, respectively.
Here the results match exactly with those in the $slopes
component of compSlopes()
.
Conclusion
The emtrends()
function in the emmeans
package provides a more general solution to comparing multiple slopes than what was used in compSlopes()
in the FSA
package (prior to v0.9.0). Thus, compSlopes()
will be removed from FSA with v0.9.0. You should use emtrends()
instead.
The emmeans
package has extensive vignettes that further explain its use. For this use case see this discussion. Their “Basics” vignette is also useful.
Note that this change to FSA
does not affect anything in the published Introductory Fisheries Analyses with R book. However, the specific analysis in this supplement to the book will no longer work as described. The use of compSlopes()
there will need to be replaced with emtrends()
.
In the next post I will demonstrate how to use emmeans()
from the emmeans
package to replace compIntercepts()
, which will also be removed from the next version of FSA
.
Footnotes

I filtered the data to only three years to reduce the amount of output below to make it easier to follow the main concepts. ↩

compSlopes()
had aprint()
function for nicely printing the results. However, here we will look at each component separately to ease comparison with theemtrends()
results. ↩ 
emmeans
does not compute pvalues by default. ↩