Allometry, is the covariation of shape with size, and is a
critically-important pattern to evaluate in morphometric analyses. Here
we show several analyses available in geomorph
for
investigating shape-size relationships.
library(geomorph)
## Loading required package: RRPP
## Loading required package: rgl
## Loading required package: Matrix
data(pupfish)
plotAllSpecimens(pupfish$coords) #NOTE: already GPA-aligned
#Y.gpa <- gpagen(pupfish$coords, print.progress = FALSE) #GPA-alignment
pupfish$logSize <- log(pupfish$CS)
pupfish$Group <- interaction(pupfish$Pop, pupfish$Sex)
fit <- procD.lm(coords ~ logSize, data = pupfish, print.progress = FALSE)
anova(fit)
##
## Analysis of Variance, using Residual Randomization
## Permutation procedure: Randomization of null model residuals
## Number of permutations: 1000
## Estimation method: Ordinary Least Squares
## Sums of Squares and Cross-products: Type I
## Effect sizes (Z) based on F distributions
##
## Df SS MS Rsq F Z Pr(>F)
## logSize 1 0.014019 0.0140193 0.24886 17.229 4.3462 0.001 **
## Residuals 52 0.042314 0.0008137 0.75114
## Total 53 0.056333
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Call: procD.lm(f1 = coords ~ logSize, data = pupfish, print.progress = FALSE)
# Predline (note: `plotAllometry` can also be used)
plot(fit, type = "regression", reg.type = "PredLine", predictor = pupfish$logSize, pch = 19)
# RegScore (note: `plotAllometry` can also be used)
plot(fit, type = "regression", reg.type = "RegScore", predictor = pupfish$logSize, pch = 19)
# CAC
plotAllometry(fit, size = pupfish$logSize, logsz = FALSE, method = "CAC", pch = 19)
M <- mshape(pupfish$coords)
preds <- shape.predictor(fit$GM$fitted, x= pupfish$logSize, Intercept = TRUE,
predmin = min(pupfish$logSize),
predmax = max(pupfish$logSize))
par(mfrow=c(1,2))
plotRefToTarget(M, preds$predmin, mag=1)
mtext("Regression Min")
plotRefToTarget(M, preds$predmax, mag=1)
mtext("Regression Max")
par(mfrow=c(1,1))
Next, we add some biological realism, and consider the case of allometry patterns in multiple groups. This, of course, represents an ANCOVA design: analysis of covariance. It requires a more complex linear model, and affords additional possibilities in terms of analytical approaches, and visualizations.
fit.common <- procD.lm(coords ~ logSize + Group,
data = pupfish, print.progress = FALSE)
fit.unique <- procD.lm(coords ~ logSize * Group,
data = pupfish, print.progress = FALSE)
anova(fit.unique)
##
## Analysis of Variance, using Residual Randomization
## Permutation procedure: Randomization of null model residuals
## Number of permutations: 1000
## Estimation method: Ordinary Least Squares
## Sums of Squares and Cross-products: Type I
## Effect sizes (Z) based on F distributions
##
## Df SS MS Rsq F Z Pr(>F)
## logSize 1 0.014019 0.0140193 0.24886 29.2078 5.0041 0.001 **
## Group 3 0.018230 0.0060766 0.32361 12.6601 6.4891 0.001 **
## logSize:Group 3 0.002004 0.0006682 0.03558 1.3921 1.1451 0.136
## Residuals 46 0.022079 0.0004800 0.39194
## Total 53 0.056333
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Call: procD.lm(f1 = coords ~ logSize * Group, data = pupfish, print.progress = FALSE)
In this case, the unique slopes are not an improvement of fit. This suggest that the slopes are relatively parallel. However, but for the purposes of illustration we will continue as if they were.
Based on the outcome of a homogeneity of slopes test, one may wish to perform different types of pairwise comparisons. These come in the form of: 1) comparisons of adjusted least-squares means (common slopes), 2) comparisons of slope angles (unique slopes), 3) comparisons of regression lengths (unique slopes), and 4) comparisons of group disparity. For the present example, #2 and #3 are most appropriate to investigate.
slope.pw <- pairwise(fit.unique, fit.null = fit.common,
groups = pupfish$Group,
covariate = pupfish$logSize, print.progress = FALSE)
summary(slope.pw, test.type = "VC", angle.type = "deg") # angular differences
##
## Pairwise comparisons
##
## Groups: Marsh.F Sinkhole.F Marsh.M Sinkhole.M
##
## RRPP: 1000 permutations
##
## Slopes (vectors of variate change per one unit of covariate
## change, by group):
## Vectors hidden (use show.vectors = TRUE to view)
##
## Pairwise statistics based on slopes vector correlations (r)
## and angles, acos(r)
## The null hypothesis is that r = 1 (parallel vectors).
## This null hypothesis is better treated as the angle
## between vectors = 0
## r angle UCL (95%) Z Pr > angle
## Marsh.F:Sinkhole.F 0.6318267 50.81498 83.57546 -0.07310658 0.527
## Marsh.F:Marsh.M 0.6139591 52.12367 83.58445 -0.13196270 0.549
## Marsh.F:Sinkhole.M 0.4461018 63.50614 81.89039 0.66791084 0.273
## Sinkhole.F:Marsh.M 0.7175129 44.15048 63.60905 0.24275646 0.391
## Sinkhole.F:Sinkhole.M 0.4627734 62.43378 60.22153 1.77232308 0.037
## Marsh.M:Sinkhole.M 0.5629975 55.73665 65.19951 1.04510764 0.154
summary(slope.pw, test.type = "dist", angle.type = "deg") # amount of shape change differences
##
## Pairwise comparisons
##
## Groups: Marsh.F Sinkhole.F Marsh.M Sinkhole.M
##
## RRPP: 1000 permutations
##
## Slopes (vectors of variate change per one unit of covariate
## change, by group):
## Vectors hidden (use show.vectors = TRUE to view)
##
## Pairwise distances between slope vector
## (end-points), plus statistics
## d UCL (95%) Z Pr > d
## Marsh.F:Sinkhole.F 0.07848121 0.1621176 -0.9763904 0.838
## Marsh.F:Marsh.M 0.08279940 0.1640452 -0.9689342 0.829
## Marsh.F:Sinkhole.M 0.12322729 0.1610484 0.7139190 0.236
## Sinkhole.F:Marsh.M 0.06418279 0.1095190 -0.3981426 0.652
## Sinkhole.F:Sinkhole.M 0.11706696 0.1001323 2.2066562 0.015
## Marsh.M:Sinkhole.M 0.10863856 0.1132783 1.5445168 0.063
Conclusion: Not much going on for this example (illustration purposes only).
This shows visually that the common slopes model is preferred.
par(mfcol = c(1,2))
plot(fit.common, type = "regression", predictor = pupfish$logSize,
reg.type = "PredLine", pch=19, col = pupfish$Group)
legend("topleft", legend = unique(pupfish$Group), pch = 21, pt.bg = unique(pupfish$Group))
mtext("Common Slopes")
plot(fit.unique, type = "regression", predictor = pupfish$logSize,
reg.type = "PredLine", pch=19, col = pupfish$Group)
legend("topleft", legend = unique(pupfish$Group), pch = 21, pt.bg = unique(pupfish$Group))
mtext("Unique Slopes")
par(mfcol = c(1,1))
One can also generate a plot of size-shape space (sensu Mitteroecker et al. 2004):
pc.plot <- plotAllometry(fit.unique, size = pupfish$logSize, logsz = FALSE, method = "size.shape", pch = 19, col = pupfish$Group)
legend("bottomleft", legend = unique(pupfish$Group), pch = 21, pt.bg = unique(pupfish$Group))
summary(pc.plot$size.shape.PCA)
## Importance of components:
## PC1 PC2 PC3 PC4 PC5 PC6
## Standard deviation 0.1474 0.01651 0.01485 0.007529 0.00707 0.006295
## Proportion of Variance 0.9647 0.01209 0.00978 0.002520 0.00222 0.001760
## Cumulative Proportion 0.9647 0.97675 0.98653 0.989050 0.99126 0.993020
## PC7 PC8 PC9 PC10 PC11 PC12
## Standard deviation 0.005656 0.004491 0.00407 0.003508 0.003013 0.002929
## Proportion of Variance 0.001420 0.000900 0.00074 0.000550 0.000400 0.000380
## Cumulative Proportion 0.994440 0.995340 0.99607 0.996620 0.997020 0.997400
## PC13 PC14 PC15 PC16 PC17 PC18
## Standard deviation 0.00262 0.002505 0.002361 0.002194 0.00212 0.001935
## Proportion of Variance 0.00030 0.000280 0.000250 0.000210 0.00020 0.000170
## Cumulative Proportion 0.99771 0.997990 0.998240 0.998450 0.99865 0.998820
## PC19 PC20 PC21 PC22 PC23 PC24
## Standard deviation 0.001782 0.001662 0.001616 0.001509 0.001413 0.001329
## Proportion of Variance 0.000140 0.000120 0.000120 0.000100 0.000090 0.000080
## Cumulative Proportion 0.998960 0.999080 0.999190 0.999300 0.999380 0.999460
## PC25 PC26 PC27 PC28 PC29 PC30
## Standard deviation 0.001123 0.001104 0.001014 0.0009936 0.0009728 0.0008576
## Proportion of Variance 0.000060 0.000050 0.000050 0.0000400 0.0000400 0.0000300
## Cumulative Proportion 0.999520 0.999570 0.999620 0.9996600 0.9997000 0.9997400
## PC31 PC32 PC33 PC34 PC35
## Standard deviation 0.0008072 0.0007869 0.0007659 0.0006959 0.000669
## Proportion of Variance 0.0000300 0.0000300 0.0000300 0.0000200 0.000020
## Cumulative Proportion 0.9997700 0.9997900 0.9998200 0.9998400 0.999860
## PC36 PC37 PC38 PC39 PC40
## Standard deviation 0.0006259 0.0005974 0.0005768 0.0005292 0.000494
## Proportion of Variance 0.0000200 0.0000200 0.0000100 0.0000100 0.000010
## Cumulative Proportion 0.9998800 0.9998900 0.9999100 0.9999200 0.999930
## PC41 PC42 PC43 PC44 PC45
## Standard deviation 0.0004724 0.0004492 0.0004368 0.0004183 0.0003844
## Proportion of Variance 0.0000100 0.0000100 0.0000100 0.0000100 0.0000100
## Cumulative Proportion 0.9999400 0.9999500 0.9999600 0.9999700 0.9999700
## PC46 PC47 PC48 PC49 PC50
## Standard deviation 0.0003406 0.0003186 0.0002964 0.0002685 0.0002631
## Proportion of Variance 0.0000100 0.0000000 0.0000000 0.0000000 0.0000000
## Cumulative Proportion 0.9999800 0.9999800 0.9999900 0.9999900 0.9999900
## PC51 PC52 PC53 PC54
## Standard deviation 0.0002355 0.000215 0.0002037 6.546e-17
## Proportion of Variance 0.0000000 0.000000 0.0000000 0.000e+00
## Cumulative Proportion 1.0000000 1.000000 1.0000000 1.000e+00