Skip to contents

Martin (2016) released laboratory-reared hybrids of the three Cyprinodon pupfish species of San Salvador Island into field enclosures in two lakes and recorded survival over three months; Martin and Wainwright (2013) describe the experiment. The package has the survival data and trait scores for each lake as crescent_pond_pupfish and little_lake_pupfish, already standardised within lake; ?crescent_pond_pupfish describes the columns. They also hold the low-density enclosures and laboratory-reared fish of the three parental species, but Martin’s analyses use the high-density enclosures only, 796 fish in Crescent Pond and 875 in Little Lake, so we keep to those. The traits are the six functional traits of Martin’s Table 3: lower jaw length (jaw), upper jaw length (pmx), nasal protrusion (nose), nasal angle (noseangle), body depth (body) and orbit diameter (eye).

library(lande)
crescent <- crescent_pond_pupfish[crescent_pond_pupfish$density == "H", ]
little <- little_lake_pupfish[little_lake_pupfish$density == "H", ]
traits <- c("jaw", "pmx", "nose", "noseangle", "body", "eye")
c(crescent = nrow(crescent), little = nrow(little))
## crescent   little 
##      796      875

Gradients in each lake

cp <- selection_report(crescent, "survival", traits, fitness_type = "binary")
cp[cp$Type == "Linear", ]
## Selection analysis (standardised traits, relative fitness)
## Fitness type: binary 
## p-values are from a logistic model on the same terms
## 
##       Term   Type Estimate Std_Error P_Value Sig
##        jaw Linear  -0.1086    0.1895  0.5595    
##        pmx Linear   0.4895    0.2074  0.0180   *
##       nose Linear   0.3580    0.1359  0.0082  **
##  noseangle Linear  -0.0727    0.1214  0.5227    
##       body Linear   0.2676    0.1485  0.0615   .
##        eye Linear  -0.1245    0.1326  0.3670    
## 
## Signif: *** 0.001  ** 0.01  * 0.05  . 0.1

In Crescent Pond survival rose with upper jaw length and nasal protrusion.

ll <- selection_report(little, "survival", traits, fitness_type = "binary")
ll[ll$Type == "Linear", ]
## Selection analysis (standardised traits, relative fitness)
## Fitness type: binary 
## p-values are from a logistic model on the same terms
## 
##       Term   Type Estimate Std_Error P_Value Sig
##        jaw Linear   0.0400    0.1185  0.7245    
##        pmx Linear   0.2025    0.1603  0.2032    
##       nose Linear   0.0343    0.1287  0.7986    
##  noseangle Linear   0.0842    0.1372  0.5785    
##       body Linear   0.4279    0.1267  0.0008 ***
##        eye Linear   0.1306    0.1083  0.1998    
## 
## Signif: *** 0.001  ** 0.01  * 0.05  . 0.1

In Little Lake survival rose with body depth and nothing else stands out.

The nasal traits in Crescent Pond

Nasal protrusion and nasal angle are one of Martin’s functional modules.

nasal <- c("nose", "noseangle")
prep <- prepare_selection_data(crescent, "survival", nasal)
surface <- correlated_fitness_surface(prep, "survival", nasal, grid_n = 50)
plot_correlated_fitness_enhanced(surface, nasal, original_data = prep, fitness_col = "survival")

The surface is drawn only within the convex hull of the fish; the highest fitted survival sits at the edge of the data, among the fish with the largest nasal protrusion.

land <- adaptive_landscape(prep, surface$model, nasal, grid_n = 30, simulation_n = 200)
plot_adaptive_landscape(land, nasal)

land$optimum_edge
## [1] TRUE

The highest mean fitness is on the edge of the grid, at the largest nasal protrusion and outside the data, so within the data the landscape has no peak.

Curvature against Martin’s Table 3

Martin fitted a spline to each trait and reported how curved it was (his Table 3): in Crescent Pond body depth most of all and upper jaw length less, and every trait in Little Lake close to straight. Here are the effective degrees of freedom of the univariate spline for each trait, with the default smoothing, which for survival is UBRE (mgcv’s "GCV.Cp" with a known scale), and with REML.

edf <- function(d, trait, smoothing) {
  prep <- prepare_selection_data(d, "survival", trait)
  summary(univariate_spline(prep, "survival", trait, smoothing = smoothing)$model)$edf
}
round(rbind(
  crescent_ubre = sapply(traits, edf, d = crescent, smoothing = "GCV.Cp"),
  crescent_reml = sapply(traits, edf, d = crescent, smoothing = "REML"),
  little_ubre = sapply(traits, edf, d = little, smoothing = "GCV.Cp"),
  little_reml = sapply(traits, edf, d = little, smoothing = "REML")
), 2)
##                jaw  pmx nose noseangle body  eye
## crescent_ubre 1.83 3.88 1.81      6.18 4.14 1.76
## crescent_reml 2.03 3.39 2.00      1.02 1.00 1.95
## little_ubre   1.64 6.85 1.00      7.44 1.52 1.00
## little_reml   1.80 1.00 1.00      1.00 1.67 1.00

Neither criterion matches his table exactly. UBRE comes close for most traits and curves body depth in Crescent Pond, though less than he found, but it also makes nasal angle in both lakes and upper jaw length in Little Lake wiggly where his splines are straight. Counting an edf of about 2 or less as close to straight, REML matches him for every trait but body depth in Crescent Pond, which it leaves straight.