General Introduction

Today we will briefly introduce some geomorph functions for performing the analyses described yesterday. Note: You should be able to read in your data and perform the analyses from earlier this week!

1: Trajectory Analysis

Here is a simple example of trajectory analysis:

data(pupfish)
fit <- procD.lm(coords ~ Pop * Sex, 
                data = Pupfish, 
                iter = 999, 
                print.progress = FALSE)

reveal.model.designs(fit)
##            Reduced                 Full                                  
## Pop              1                  Pop                                  
## Sex            Pop            Pop + Sex                                  
## Pop:Sex  Pop + Sex  Pop + Sex + Pop:Sex <- Null/Full inherent in pairwise
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)    
## Pop        1 0.008993 0.0089927 0.15964 16.076 3.9997  0.001 ***
## Sex        1 0.015917 0.0159169 0.28255 28.453 4.1103  0.001 ***
## Pop:Sex    1 0.003453 0.0034532 0.06130  6.173 3.7015  0.001 ***
## Residuals 50 0.027970 0.0005594 0.49651                         
## Total     53 0.056333                                           
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Call: procD.lm(f1 = coords ~ Pop * Sex, iter = 999, data = Pupfish,  
##     print.progress = FALSE)
TA <- trajectory.analysis(fit, 
                          groups = Pupfish$Pop, 
                          traj.pts = Pupfish$Sex)

summary(TA, attribute = "MD") # Magnitude difference (absolute difference between path distances)
## 
## Trajectory analysis
## 
## 1000 permutations.
## 
## Points projected onto trajectory PCs
## 
## Trajectories:
## Trajectories hidden (use show.trajectories = TRUE to view)
## 
## Observed path distances by group
## 
##      Marsh   Sinkhole 
## 0.04611590 0.02568508 
## 
## Pairwise absolute differences in path distances, plus statistics
##                         d  UCL (95%)       Z Pr > d
## Marsh:Sinkhole 0.02043082 0.01274369 2.66641  0.001
summary(TA, attribute = "TC", angle.type = "deg") # Correlations (angles) between trajectories
## 
## Trajectory analysis
## 
## 1000 permutations.
## 
## Points projected onto trajectory PCs
## 
## Trajectories:
## Trajectories hidden (use show.trajectories = TRUE to view)
## 
## Pairwise correlations between trajectories, plus statistics
##                        r    angle UCL (95%)        Z Pr > angle
## Marsh:Sinkhole 0.7393716 42.32209  23.72507 3.601856      0.001
# Plot results
TP <- plot(TA, 
           pch = as.numeric(Pupfish$Pop) + 20, 
           bg = as.numeric(Pupfish$Sex),
           cex = 0.7, col = "gray")

add.trajectories(TP, 
                 traj.pch = c(21, 22), 
                 start.bg = 1, 
                 end.bg = 2)

legend("topright", 
       levels(Pupfish$Pop), 
       pch =  c(21, 22), 
       pt.bg = 1)

2: Disparity Analysis

Here is a simple example of a disparity analysis:

data("pupfish")

Group <- pupfish$Group <- interaction(pupfish$Pop, pupfish$Sex)

fit <- procD.lm(coords ~ Group, data = pupfish)

PW <- pairwise(fit, groups = Group)

summary(PW, test.type = "var")
## 
## Pairwise comparisons
## 
## Groups: Marsh.F Sinkhole.F Marsh.M Sinkhole.M 
## 
## RRPP: 1000 permutations
## 
## 
## Observed variances by group
## 
##      Marsh.F   Sinkhole.F      Marsh.M   Sinkhole.M 
## 0.0003439300 0.0005803226 0.0003607052 0.0008318581 
## 
## Pairwise distances between variances, plus statistics
##                                  d    UCL (95%)         Z Pr > d
## Marsh.F:Sinkhole.F    2.363925e-04 0.0002473769  1.518166  0.053
## Marsh.F:Marsh.M       1.677513e-05 0.0002492051 -1.346688  0.902
## Marsh.F:Sinkhole.M    4.879280e-04 0.0002412492  3.180101  0.001
## Sinkhole.F:Marsh.M    2.196174e-04 0.0002806646  1.160169  0.130
## Sinkhole.F:Sinkhole.M 2.515355e-04 0.0002726187  1.441515  0.075
## Marsh.M:Sinkhole.M    4.711529e-04 0.0002662683  2.741881  0.002
# ALTERNATIVELY
MD <- morphol.disparity(fit, print.progress = FALSE)
## 
##  *** Attempting to define groups from terms in the model fit. If results are peculiar, define groups precisely and check model formula.)
summary(MD)
## 
## Call:
## morphol.disparity(f1 = fit, print.progress = FALSE) 
## 
## 
## 
## Randomized Residual Permutation Procedure Used
## 1000 Permutations
## 
## Procrustes variances for defined groups
##      Marsh.F      Marsh.M   Sinkhole.F   Sinkhole.M 
## 0.0003439300 0.0003607052 0.0005803226 0.0008318581 
## 
## 
## Pairwise absolute differences between variances
##                 Marsh.F      Marsh.M   Sinkhole.F   Sinkhole.M
## Marsh.F    0.000000e+00 1.677513e-05 0.0002363925 0.0004879280
## Marsh.M    1.677513e-05 0.000000e+00 0.0002196174 0.0004711529
## Sinkhole.F 2.363925e-04 2.196174e-04 0.0000000000 0.0002515355
## Sinkhole.M 4.879280e-04 4.711529e-04 0.0002515355 0.0000000000
## 
## 
## P-Values
##            Marsh.F Marsh.M Sinkhole.F Sinkhole.M
## Marsh.F      1.000   0.902      0.053      0.001
## Marsh.M      0.902   1.000      0.130      0.002
## Sinkhole.F   0.053   0.130      1.000      0.075
## Sinkhole.M   0.001   0.002      0.075      1.000
P <- plot(fit, type = "PC", pch = 21, bg = pupfish$Group)

shapeHulls(P, 
           Group, 
           group.cols = c(1, 3, 2, 4))

3: Integration and Modularity

Here are SOME of the integration/modularity analyses available:

Overall Integration (and comparing it across regions)

data("plethodon")

Y.gpa <- gpagen(plethodon$land, 
                print.progress = FALSE)
  #Separate data by species

coords.gp <- coords.subset(Y.gpa$coords, 
                           plethodon$species)

#Z_Vrel by species
Vrel.gp <- Map(function(x) integration.Vrel(x), coords.gp) 

compare.ZVrel(Vrel.gp$Jord, Vrel.gp$Teyah)
## 
## Effect sizes
## 
##  Vrel.gp$Jord Vrel.gp$Teyah 
##    -0.2978931    -0.2642648 
## 
## Effect sizes for pairwise differences in rel.eig effect size
## 
##               Vrel.gp$Jord Vrel.gp$Teyah
## Vrel.gp$Jord    0.00000000    0.09804249
## Vrel.gp$Teyah   0.09804249    0.00000000
## 
## P-values
## 
##               Vrel.gp$Jord Vrel.gp$Teyah
## Vrel.gp$Jord     1.0000000     0.9218986
## Vrel.gp$Teyah    0.9218986     1.0000000

Integration among subsets

data(pupfish) # GPA previously performed

group <- factor(paste(pupfish$Pop, pupfish$Sex, sep = "."))

# Subset 3D array by group, returning a list of 3D arrays
tail.LM <- c(1:3, 5:9, 18:38)
head.LM <- (1:56)[-tail.LM]
tail.coords <- pupfish$coords[tail.LM, , ]
head.coords <- pupfish$coords[head.LM, , ]

IT <- integration.test(tail.coords, 
                       head.coords, 
                       print.progress = FALSE)
## 
## No names for A2.  Data are assumed to be ordered as in A.
summary(IT)
## 
## Call:
## integration.test(A = tail.coords, A2 = head.coords, print.progress = FALSE) 
## 
## 
## 
## r-PLS: 0.917
## 
## Effect Size (Z): 5.4983
## 
## P-value: 0.001
## 
## Based on 1000 random permutations
plot(IT)

Compare Strength of Integration acrouss groups

tail.coords.gp <- coords.subset(tail.coords, group)

head.coords.gp <- coords.subset(head.coords, group)

# Obtain Integration for groups
integ.tests <- Map(function(x,y) 
  integration.test(x, y, iter = 999, 
                print.progress = FALSE), 
  head.coords.gp, tail.coords.gp)

compare.pls(integ.tests)
## 
## Effect sizes
## 
##    Marsh.F    Marsh.M Sinkhole.F Sinkhole.M 
##  3.1956225  1.4571455  0.6488562  2.7097203 
## 
## Effect sizes for pairwise differences in PLS effect size
## 
##              Marsh.F   Marsh.M Sinkhole.F Sinkhole.M
## Marsh.F    0.0000000 0.9283614  1.9682801   0.877886
## Marsh.M    0.9283614 0.0000000  0.7894939   1.491679
## Sinkhole.F 1.9682801 0.7894939  0.0000000   2.172603
## Sinkhole.M 0.8778860 1.4916787  2.1726031   0.000000
## 
## P-values
## 
##               Marsh.F   Marsh.M Sinkhole.F Sinkhole.M
## Marsh.F    1.00000000 0.3532201 0.04903581  0.3800056
## Marsh.M    0.35322012 1.0000000 0.42982338  0.1357834
## Sinkhole.F 0.04903581 0.4298234 1.00000000  0.0298102
## Sinkhole.M 0.38000560 0.1357834 0.02981020  1.0000000

Modularity

land.gp <- rep(1,56); land.gp[tail.LM] <- 2

MT <- modularity.test(pupfish$coords,
                      land.gp,
                      CI = FALSE,
                      print.progress = FALSE)

summary(MT)
## 
## Call:
## modularity.test(A = pupfish$coords, partition.gp = land.gp, CI = FALSE,  
##     print.progress = FALSE) 
## 
## 
## 
## CR: 0.8771
## 
## P-value: 0.003
## 
## Effect Size: -4.5427
## 
## Based on 1000 random permutations
plot(MT)

Compare Strength of Modularity Across Groups

coords.gp <- coords.subset(pupfish$coords, group)

modul.tests <- Map(function(x) 
  modularity.test(x, 
                  land.gp,
                  print.progress = FALSE), 
  coords.gp) 

compare.CR(modul.tests, CR.null = FALSE)
## 
##  NOTE: more negative effects represent stronger modular signal! 
## 
## 
## Effect sizes
## 
##    Marsh.F    Marsh.M Sinkhole.F Sinkhole.M 
##  -2.816188  -5.778451  -3.363544  -4.534488 
## 
## Effect sizes for pairwise differences in CR effect size
## 
##             Marsh.F   Marsh.M Sinkhole.F Sinkhole.M
## Marsh.F    0.000000 2.5466647  1.8303913   1.017783
## Marsh.M    2.546665 0.0000000  0.1496676   1.693290
## Sinkhole.F 1.830391 0.1496676  0.0000000   1.251317
## Sinkhole.M 1.017783 1.6932905  1.2513171   0.000000
## 
## P-values
## 
##               Marsh.F    Marsh.M Sinkhole.F Sinkhole.M
## Marsh.F    1.00000000 0.01087579 0.06719144 0.30878104
## Marsh.M    0.01087579 1.00000000 0.88102690 0.09040019
## Sinkhole.F 0.06719144 0.88102690 1.00000000 0.21081881
## Sinkhole.M 0.30878104 0.09040019 0.21081881 1.00000000

4: Data Prep/Clean-up

Estimating Missing Data

NOTE: First we create some missing data for illustration
data(plethodon)

Y.gpa <- gpagen(plethodon$land, print.progress = FALSE)

plethland<-Y.gpa$coords
  plethland[3, , 2] <- plethland[8, , 2] <- NA  #create missing landmarks
  plethland[3, , 5] <- plethland[8, , 5] <- plethland[9,,5] <- NA  
  plethland[3, , 10] <- NA  

Now estimate

new.tps <- estimate.missing(plethland, method = "TPS")
new.reg <- estimate.missing(plethland, method = "Reg")
Fix Positional Differences among regions

See fixed.angle

Combine landmark configurations

See combine.subsets

5: Things to Explore on Your Own

  1. Remember Days 1 - 4
  2. Perform phylogenetic ANOVA, phylogenetic PLS, and other PCMs.
  3. Visualize shapes from everything!
  4. Plot summaries from these analyses to accompany the statistical findings
  5. Explore function options and output (there are many!)