Important Note: If the R code (.rmd file) does not work when trying to rerun the analysis, one issue may be that the datasets (the .xlsx and/or .csv files) and additional images (i.e., the .png files) must be in the same working environment (usually the same folder) as the .rmd file. If possible, make sure the supplementary figures are in the same folder as the R Code. In the event that this is not possible, deactivate the chunks that contain references to supplementary figures or delete these lines from the R Code.
1 Loading in data
<-readxl::read_excel("Arthrodire Mouths Supplementary File 1 (Data).xlsx") %>%
data_mouthsfilter(is.na(Specimen)|Specimen!="FMNH PF 1090") %>% #This specimen removed because its proportions are unusual and the specimen may not be complete
rename(genus=Genus,
species=Species,
clade=Clade,
order=Order,
family=Family,
shape=Shape,
specimen=Specimen,
ontogeny="Ontogenetic Status",
extinct=Extinct,
reference=Reference,
total_length="Total Length (cm)",
precaudal_length="Precaudal Length (cm)",
head_length="Head Length (cm)",
prebranchial_length="Prebranchial Length (cm)",
mouth_length="Mouth Length (cm)",
mouth_width="Mouth Width (cm)",
inner_mouth_width="Inner Mouth Width (cm)",
UJP="UJP (cm)")%>%
mutate(shape=factor(shape,ordered=T,levels=c("macruriform","anguilliform","elongate",
"fusiform","compressiform","flattened")),
taxon = paste0(genus," ",species))
1.1 Separating out fossil taxa
<-data_mouths%>%
(fossil_taxa_mouthsfilter(extinct==T)%>%
mutate(specimen2=paste0(genus,"_",specimen))%>%
column_to_rownames("specimen2"))
1.2 Loading shark data from Lowry et al. (2009) used by Ferron et al. 2017
<-read_excel("Arthrodire Mouths Supplementary File 2 (Lowry et al. Shark Data).xlsx")%>%
lowry_sharksrename(UJP=`UJP(cm)`,total_length=`TBL(cm)`,fork_length=`Fork Length (cm)`,precaudal_length=`Precaudal Length (cm)`,taxon=Species)%>%
mutate(species2=taxon)%>%
separate(species2,c("genus","species"))%>%
mutate(family=case_when(genus %in% c("Carcharodon","Isurus") ~ "Lamnidae",
%in% c("Sphyrna") ~ "Sphyrnidae",
genus %in% c("Carcharhinus","Galeocerdo","Negaprion") ~ "Carcharhinidae"
genus
),percent_body=precaudal_length/total_length)
1.3 Loading in jaw data for FSBC sharks
<-read_excel("Arthrodire Mouths Supplementary File 3 (FSBC Shark Jaws).xlsx")
fsbc_sharks
#Adding rows for FSBC sharks to main dataset
<-data_mouths%>%
data_mouthsadd_row(fsbc_sharks%>%
select(taxon,specimen,mouth_width,UJP,total_length,precaudal_length)%>%
separate(.,taxon,into=c("genus","species"),sep=" ",remove=F)%>%
mutate(clade="Chondrichthyes",
reference="Present Study",
order=case_when(genus %in% c("Hexanchus","Heptranchias")~"Hexanchiformes",
%in% c("Galeocerdo","Carcharhinus",
genus "Hemipristis")~"Carcharhiniformes",
%in% c("Odontaspis")~"Lamniformes"),
genus family=case_when(genus %in% c("Hexanchus","Heptranchias")~"Hexanchiidae",
%in% c("Galeocerdo","Carcharhinus")~"Carcharhinidae",
genus %in% c("Hemipristis")~"Hemigaleidae",
genus %in% c("Odontaspis")~"Odontaspidae"))) genus
2 Data
2.1 Measurements
Measurement | Variable Name | Definition |
---|---|---|
Total length | total_length | Length from anterior tip of rostrum to posterior tip of caudal fin |
Precaudal length | precaudal_length | Length from anterior tip of rostrum to posterior tip of caudal peduncle |
Head length | head_length | Length from anterior tip of rostrum to posterior margin of branchial cavity For sharks: from snout to opening of terminal gill arch For osteichthyans: from snout to posterior end of operculum For arthrodires: from snout to cranio-thoracic joint |
Prebranchial length | prebranchial_length | distance from tip of snout to anterior end of branchial skeleton For sharks: to opening for first gill slit For osteichthyans: to anterior end of opercular series For arthrodires: not distinguishable |
Upper jaw perimeter | UJP | Perimeter of upper jaw measured from bilateral angle of jaws |
Mouth width | mouth_width | Bilateral width of mouth across external angles of the jaw |
Inner mouth width | inner_mouth_width | Bilateral width of mouth across inner angles of the jaw |
Mouth length | mouth_length | Length of mouth along anteroposterior axis For sharks: anteroposterior length from the mandibular symphysis to the angle of the jaws For osteichthyans: anteroposterior length of upper jaw For arthrodires: anteroposterior length from tip of supragnathals to point where supraoral sensory line meets margin of jaw |
Note: Most of these differences between definitions in taxa are due to the presence of an operculum (in osteichthyans and chimaeroids) or the incorporation of the cranium and gill covers as single unit (i.e., the cheek plates of arthrodires). Thus, despite the differing definitions these measurements are anatomically homologous.
2.2 Taxonomic distribution of observations
%>%
data_mouthsdrop_na(total_length)%>%
group_by(clade)%>%
summarise(N=n(),Taxa=n_distinct(taxon))%>%
add_row(clade="All Species",
N=data_mouths%>%
drop_na(total_length)%>%
summarise(N=n())%>%pull(),
Taxa=data_mouths%>%
drop_na(total_length)%>%
summarise(Taxa=n_distinct(taxon))%>%pull())%>%
kable(col.names=c("Clade","# Occurences","# Taxa"),
align=c("l","c","c"),
caption="Taxonomic distribution of observations made in this study. Placoderms for which only head dimensions are available (e.g., <i>Dunkleosteus</i>) are excluded from this table.")%>%
row_spec(5, bold = T)%>%
kable_styling()
Clade | # Occurences | # Taxa |
---|---|---|
Actinopterygii | 2356 | 792 |
Chondrichthyes | 782 | 180 |
Placodermi | 17 | 10 |
Sarcopterygii | 16 | 3 |
All Species | 3171 | 985 |
3 Additional notes on data collection
3.1 Method of collecting measurements in Arthrodira
In collecting data for arthrodires, it was often necessary to make use of reconstruction or composite specimens. This is because most complete arthrodires are preserved on flattened slabs, and thus it is not possible to measure total length and mouth dimensions in the same specimens. Even when arthrodires are extracted from the rock to create 3D reconstructions (e.g., the Gogo Formation arthrodires or Plourdosteus in Vézina 1988), this typically results in the post-thoracic axial skeleton being left behind because it is too fragile to mount. This means relative mouth size can only be measured in a very small number of arthrodires. Additional information on how measurements were collected in arthrodires are detailed below.
The early middle Devonian (Givetian) Coccosteus cuspidatus is the best known arthrodire in terms of its post-thoracic anatomy, having been described in detail by Miles & Westoll (1968). For this study, morphometric data for Coccosteus cuspidatus (UJP, mouth width, and head length) was taken from the reconstructions in Miles & Westoll (1968). This reconstructions are derived from several individuals, but when the dimensions of this reconstruction are compared to specimens of Coccosteus they appear to accurately reflect the proportions of this species. The reconstruction of C. cuspidatus in Miles & Westoll (1968: fig. 48) has a total length of 39.4 cm (scale is not provided for fig. 48, but total length can be estimated from head length, which is provided in fig. 23b).
Mouth width, but not UJP, could be measured in three additional arthrodires known from complete remains: Holonema westolii (see Miles & White 1971; Trinajstic 1999), Plourdosteus canadensis (see Vézina 1988; Vézina 1990), and Incisoscutum ritchei (see Dennis & Miles 1981; Trinajstic et al. 2013). Mouth width in two other species, Watsonosteus fletti and Millerosteus minor, could not be measured directly but could be approximated based on the preserved extent of the specimens (measuring from the approximate distance between the ends of the supraoral lateral line). For H. westolii, the skull of this taxon is figured in a splayed out, slightly crushed fashion in Miles & White (1971: fig. 4), but this depiction was considered close enough to the actual skull dimensions to highlight the traits of interest.
Measurements of Plourdosteus canadensis were taken from MNHN 2-177, which is (was) a complete skeleton of P. canadensis preserving the entire animal from the rostral plate to the tip of the vertebral column (only missing the soft tissue outline of the caudal fin). Originally preserved as a flattened plate, Vézina (1988) extracted the skull and trunk armor to produce a three-dimensional mount (Vézina 1988: plates 1-2), leaving the post-thoracic skeleton in this matrix (this material currently catalogued as MNHM 02-177c). Head and thoracic armor measurements were taken from the figures in Vézina (1988), whereas the post-thoracic armor length was measured based on photos of MNHM 02-177c provided by J. Kerr. Unfortunately, there are no pictures of this specimen prior to preparation (J. Kerr, pers. comm.), so it is difficult to determine exactly how long this specimen originally was. Assuming the remaining postthoracic material represents the body posterior to the end of the ventral shield, as implied by hollows left by the extraction of plates (posteroventrolaterals?) and a large element at the preserved anterior end of the skeleton that appears to represent a clasper or iliac process of the pelvic girdle MNHM 02-177c would have been about 37.5 cm long originally. The same author (Vézina 1990) later provides a full-body lateral reconstruction of P. canadensis. However, this reconstruction shows features that make its proportions suspect, including a post-thoracic region that appears to be directly copied from the figure of C. cuspidatus in Miles & Westoll (1968), albeit with a modified pelvic girdle, rather than reflecting the proportions of Plourdosteus specimens. Therefore, the preserved dimensions of MNHM 02-177 seem more reliable for estimating the proportions of this species. It was not possible to contact D. Vézina for clarification on this specimen as this researcher is now deceased (J. Kerr, pers. comm.).
Finally, for Incisoscutum ritchei, the reconstruction presented in Trinajstic et al. (2013: fig. 1c) was used as a starting point, and then the material was cross-referenced and scaled with Incisoscutum fossil material (NHMUK P50923 and WAM 0.3.3.28). The proportions of this reconstruction were similar enough to actual fossils of I. ritchei that this reconstruction was considered a reliable representation of the proportions of Incisoscutum. Mouth width for Incisoscutum was calculating by scaling the mouth width of NKMUK PV P 50929 (Dennis & Miles 1981: fig. 9) to the size of the reconstruction in Trinajstic et al. (2013) using skull length. This ensured mouth width was measured directly from fossil specimens of I. ritchei. The skull of NHMUK PV P 50929 is similar in size to the reconstruction in Trinajstic et al. (2013) (5.75 versus 5.74 cm), suggesting bias from allometric scaling, if it exists, should be minor.
Notably, the reconstruction of Incisoscutum in Trinajstic et al. (2013: fig. 1c) lacks the caudal fin. This is because none of the eubrachythoracid arthrodires from the Gogo Formation preserves an associated caudal fin (Trinajstic et al. 2022; Trinajstic pers. comm.). Thus, despite the Gogo Formation producing a significant number of extremely well-preserved arthrodire specimens, none of this material can be used to determine the body proportions or overall length of arthrodires. Because complete arthrodires are so rare and the precaudal anatomy of Incisoscutum is completely known, total length was estimated for I. ritchei assuming the the caudal fin represented ~32% of total length (i.e., total length/precaudal length = 1.46). This is the proportion between caudal fin length and total length in the reconstruction of Coccosteus cuspidatus in Miles and Westoll (1968). Additionally, this ratio is similar to the total length/precaudal length ratio in many extant sharks (see below), suggesting it represents a reasonable approximation for I. ritchei.
For Millerosteus minor, initially no complete specimens of Millerosteus minor could be observed for this study. Instead, composite values for Millerosteus were calculated using the armor proportions of the specimen described by Desmond (1974) (C.369 of that study, currently cataloged as LDUCZ-V998), which preserves most of the armor but very little of the axial skeleton (Desmond 1974: pl. 1) and the postthoracic dimensions of an undescribed specimen of M. minor collected by M. J. Newman. The Newman specimen is missing the middle caudal vertebrae but preserves the remainder of the post-thoracic skeleton, including the dorsal fin, pelvic girdle, anal plate, and distal caudal vertebrae to the caudal fin tip. The specimen measured 6.325 cm from the snout to the end of the ventral armor and has an approximate total length of 17 cm. The postthoracic dimensions of this specimen were scaled to that of LDUCZ-V998 using the length of the specimen to the end of the ventral armor. The skull of Newman’s specimen is poorly preserved, the outline of the head can be distinguished but the rest of the cranial anatomy cannot. Thus, it cannot be used on its own. Mouth width in Millerosteus was approximated by measuring between the ventral ends of the supraoral sensory canal. Late in the study it was possible to access specimens of Millerosteus in the Field Museum of Natural History, but mouth width could not be measured in these specimens.
3.2 Length-length equations for sharks
In evaluating the dataset of Lowry et al. (2009) it was also of interest to see whether caudal fin proportions between the various groups examined might signficantly bias the allometric relationships seen between UJP and total length in sharks. Therefore, total length was converted to precaudal length for each shark using the length-length equations in Branstetter & Stiles (1987), Cliff (1995), Francis (2006), Piercy et al. (2007), Whitney & Crow (2007), and Pollack et al. (2019). For Isurus paucus no length-length equation was available, so one was created using the data from Garrick (1967) and Gilmore (1983).
3.3 Note on the ventral armor of Dunkleosteus
For the reconstruction of the armor of Dunkleosteus in the manuscript, the specimen is depicted as is with no alterations. The figure was drawn directly from images of the specimen, and so represents the actual proportions of the material.
The only modification made was that the Dunkleosteus specimens were reconstructed with a curved ventral shield, rather than the flattened one seen in the mounted specimens. This is because three-dimensionally preserved fossils of arthrodires show the ventral armor of marine arthrodires was naturally curved (e.g., Gardiner & Miles 1994; Miles & Dennis 1979), and thus these animals had a torpedo-like cross-section. However, this discovery was made long after the Dunkleosteus specimens at the CMNH were mounted (circa 1929; J. Tait, pers. comm.). However, after it was discovered arthrodires naturally had curved ventral armor, retrodeformation of the ventral shield was deemed too destructive to the original material because it involved manually breaking and resetting the specimens (D. Chapman, pers. comm.). Thus, the CMNH Dunkleosteus have retained their flattened ventral armor despite this feature otherwise being outdated. Despite being mounted with flat ventral armor, depicting the specimens as such would not accurately depict the anatomy of this taxon and would result in the body appearing unrealistically boxy. Thus, the ventral curvature of the armor was approximated based on the curvature of the specimens.
5 Comparison of estimates using upper jaw perimeter and mouth width
5.1 Specimen-level analysis
Note: Alopias spp. and Chimaeriformes were excluded for this model.
<-lm(log(total_length)~log(mouth_width),
fit.mouthwidth%>%
data_mouthsfilter(clade=="Chondrichthyes",
!= "Chimaeriformes",
order !="Alopias"))
genussummary(fit.mouthwidth)
##
## Call:
## lm(formula = log(total_length) ~ log(mouth_width), data = data_mouths %>%
## filter(clade == "Chondrichthyes", order != "Chimaeriformes",
## genus != "Alopias"))
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.88416 -0.13332 0.00318 0.13206 0.62083
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 2.89884 0.02241 129.38 <2e-16 ***
## log(mouth_width) 0.81568 0.01032 79.06 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.2114 on 623 degrees of freedom
## (117 observations deleted due to missingness)
## Multiple R-squared: 0.9094, Adjusted R-squared: 0.9092
## F-statistic: 6251 on 1 and 623 DF, p-value: < 2.2e-16
regression.stats(fit.mouthwidth)
5.1.1 Diagnostic plots
par(mfrow=c(2,2))
plot(fit.mouthwidth)
Based on these diagnostic plots the residuals are normally distributed, homoskedastic, have no outliers with significant leverage, and suggest a linear model, thus should be safe to use to predict new data.
5.1.2 Allometric relationship
For this analysis total_length
was set as the independent variable, to better express changes in proportion in mouth_width
across chondrichthyans of different sizes.
%>%
data_mouthsfilter(clade=="Chondrichthyes",!order %in% c("Chimaeriformes"),
!="Alopias")%>%
genusdrop_na(mouth_width,total_length)%$%
lm(log(mouth_width)~log(total_length),.)%>%
summary()
##
## Call:
## lm(formula = log(mouth_width) ~ log(total_length), data = .)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.68930 -0.16680 -0.01405 0.15583 0.99567
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -3.04952 0.06477 -47.08 <2e-16 ***
## log(total_length) 1.11486 0.01410 79.06 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.2471 on 623 degrees of freedom
## Multiple R-squared: 0.9094, Adjusted R-squared: 0.9092
## F-statistic: 6251 on 1 and 623 DF, p-value: < 2.2e-16
5.2 Examining the allometric relationship of mouth width using species averages
5.2.1 Regression equation
Note: Alopias spp. and Chimaeriformes were excluded for this model. Only adult and subadult (that is, large but not sexually mature) specimens were considered for this analysis.
<-data_mouths%>%
fit.mouthwidth_averagesfilter(is.na(ontogeny)|ontogeny %in% c("adult","subadult"),
=="Chondrichthyes",!order %in% c("Chimaeriformes"),
clade!="Alopias")%>%
genusdrop_na(mouth_width,total_length)%>%
group_by(taxon)%>%
summarise(mouth_width=mean(mouth_width),total_length=mean(total_length),order=unique(order))%$%
lm(log(total_length)~log(mouth_width),.)
summary(fit.mouthwidth_averages)
##
## Call:
## lm(formula = log(total_length) ~ log(mouth_width), data = .)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.68961 -0.13979 0.01145 0.15040 0.47539
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 2.93694 0.05053 58.12 <2e-16 ***
## log(mouth_width) 0.80555 0.02277 35.37 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.2191 on 154 degrees of freedom
## Multiple R-squared: 0.8904, Adjusted R-squared: 0.8897
## F-statistic: 1251 on 1 and 154 DF, p-value: < 2.2e-16
regression.stats(fit.mouthwidth_averages)
5.2.2 Allometric relationship
For this analysis total_length
was set as the independent variable, to better express changes in proportion in mouth_width
across chondrichthyans of different sizes.
%>%
data_mouthsfilter(is.na(ontogeny)|ontogeny %in% c("adult","subadult"),
=="Chondrichthyes",!order %in% c("Chimaeriformes"),
clade!="Alopias")%>%
genusdrop_na(mouth_width,total_length)%>%
group_by(taxon)%>%
summarise(mouth_width=mean(mouth_width),total_length=mean(total_length),order=unique(order))%$%
lm(log(mouth_width)~log(total_length),.)%>%
summary()
##
## Call:
## lm(formula = log(mouth_width) ~ log(total_length), data = .)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.58011 -0.17469 -0.01593 0.16287 0.73161
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -3.01826 0.14561 -20.73 <2e-16 ***
## log(total_length) 1.10534 0.03125 35.37 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.2567 on 154 degrees of freedom
## Multiple R-squared: 0.8904, Adjusted R-squared: 0.8897
## F-statistic: 1251 on 1 and 154 DF, p-value: < 2.2e-16
5.3 Comparison of estimates using UJP and mouth width in arthrodires
<-lm(total_length~UJP,lowry_sharks)
fit.UJPsummary(fit.UJP)
##
## Call:
## lm(formula = total_length ~ UJP, data = lowry_sharks)
##
## Residuals:
## Min 1Q Median 3Q Max
## -64.184 -24.385 -7.079 18.818 159.091
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 48.6599 5.0565 9.623 <2e-16 ***
## UJP 5.3305 0.1396 38.185 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 35.28 on 243 degrees of freedom
## Multiple R-squared: 0.8572, Adjusted R-squared: 0.8566
## F-statistic: 1458 on 1 and 243 DF, p-value: < 2.2e-16
# Predictions of total length using UJP and mouth width
<-fossil_taxa_mouths%>%
mouth_predictionsdrop_na(UJP,mouth_width)%>%
augment(x=fit.UJP,newdata=.,interval="prediction") %>%
rename_at(vars(starts_with('.')), funs(paste0('fit.UJP', .)))%>%
augment(x=fit.mouthwidth,newdata=.,interval="prediction") %>%
rename_at(vars(starts_with('.')), funs(paste0('fit.mouth_width', .)))%>%
rename(mouth_width_original=mouth_width,
mouth_width=inner_mouth_width)%>%
augment(x=fit.mouthwidth,newdata=.,
interval="prediction") %>%
rename_at(vars(starts_with('.')), funs(paste0('fit.inner_mouth_width', .)))%>%
rename(mouth_width=mouth_width_original,
inner_mouth_width=mouth_width)%>%
mutate(across(fit.mouth_width.fitted:fit.inner_mouth_width.upper,
~exp(.)*regression.stats(fit.mouthwidth)$CF),
fit.UJP.range=paste0("(",round(fit.UJP.lower,1),"–",round(fit.UJP.upper,1),")"),
fit.mouth_width.range=paste0("(",round(fit.mouth_width.lower,1),"–",
round(fit.mouth_width.upper,1),")"),
fit.inner_mouth_width.range=paste0("(",round(fit.inner_mouth_width.lower,1),"–",
round(fit.inner_mouth_width.upper,1),")"))
# Kable of results
%>%
mouth_predictionsarrange(UJP)%>%
mutate(diff_pred1=100*abs(fit.UJP.fitted-fit.mouth_width.fitted)/fit.mouth_width.fitted,
diff_pred2=100*abs(fit.UJP.fitted-fit.inner_mouth_width.fitted)/fit.inner_mouth_width.fitted)%>%
select(taxon,specimen,UJP,fit.UJP.fitted,fit.UJP.range,
mouth_width,fit.mouth_width.fitted,fit.mouth_width.range,diff_pred1,%>%
inner_mouth_width,fit.inner_mouth_width.fitted,fit.inner_mouth_width.range,diff_pred2) kable(digits=2,
align=c("l",rep("c",11)),
col.names=c("Taxon","Specimen",
"UJP","Est.","95% C.I.",
"Mouth Width","Est.","95% C.I.","% Dif.",
"Inner Mouth Width","Est.","95% C.I.","% Dif."),
caption="Comparison of total length estimates using upper jaw perimeter and mouth width. Length estimates using both are relatively similar, suggesting mouth width is an appropriate approximation of upper jaw perimeter. All measurements in cm.")%>%
column_spec(1, italic = T)%>%
column_spec(c(4,7,11), bold = T)%>%
add_header_above(c(" "=2,"Upper Jaw Perimeter"=3,"Mouth Width"=4,"Inner Mouth Width"=4))%>%
kable_styling()%>%
scroll_box(width = "100%")
Taxon | Specimen | UJP | Est. | 95% C.I. | Mouth Width | Est. | 95% C.I. | % Dif. | Inner Mouth Width | Est. | 95% C.I. | % Dif. |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Coccosteus cuspidatus | Recon. (M & W 1968) | 9.78 | 100.79 | (30.9–170.7) | 6.87 | 89.10 | (58.8–135) | 13.13 | 6.10 | 80.84 | (53.4–122.5) | 24.68 |
Dunkleosteus terrelli | CMNH 7424 | 51.00 | 320.51 | (250.7–390.3) | 29.99 | 296.39 | (195.5–449.5) | 8.14 | 21.28 | 224.04 | (147.8–339.6) | 43.06 |
Dunkleosteus terrelli | CMNH 6090 | 91.00 | 533.73 | (462.3–605.2) | 51.40 | 459.96 | (303.1–698.1) | 16.04 | 40.40 | 377.93 | (249.1–573.4) | 41.22 |
Dunkleosteus terrelli | CMNH 7054 | 99.00 | 576.38 | (504.4–648.4) | 52.00 | 464.34 | (305.9–704.8) | 24.13 | 40.65 | 379.84 | (250.4–576.3) | 51.74 |
Dunkleosteus terrelli | CMNH 5768 | 120.00 | 688.32 | (614.6–762) | 71.63 | 602.96 | (397–915.8) | 14.16 | 53.80 | 477.41 | (314.5–724.6) | 44.18 |
5.4 Testing accuracy of UJP and mouth width in estimating total length in sharks
%>%
fsbc_sharksmutate(fit_ujp=predict(fit.UJP,.,interval="prediction")[,1],
lwr_ujp=predict(fit.UJP,.,interval="prediction")[,2],
upr_ujp=predict(fit.UJP,.,interval="prediction")[,3],
PE_ujp=((fit_ujp-total_length)/fit_ujp)*100,
fit_mouth=exp(predict(fit.mouthwidth,.,interval="prediction")[,1]),
lwr_mouth=exp(predict(fit.mouthwidth,.,interval="prediction")[,2]),
upr_mouth=exp(predict(fit.mouthwidth,.,interval="prediction")[,3]),
PE_mouth=((fit_mouth-total_length)/fit_mouth)*100)%>%
column_to_rownames("specimen")%>%
select(taxon,total_length,fit_ujp,lwr_ujp,upr_ujp,PE_ujp,fit_mouth,lwr_mouth,upr_mouth,PE_mouth)%>%
mutate(est_diff=100*abs(fit_ujp-fit_mouth)/fit_mouth)%>%
kable(digits=1,
align=c("l","c","c","c","c","c","c","c","c","c","c"),
caption="Testing the accuracy of upper jaw perimeter and mouth width in estimating the total length of sharks of known length. Specimens of <i>Rhizoprionodon terranovae</i>, <i>Carcharhinus acronotus</i>, and the uncataloged specimen of <i>Galeocerdo cuvieri</i> were measured off of external measurements of fluid-preserved specimens, whereas measurements of <i>Carcharhinus leucas</i> and all other specimens of <i>Galeocerdo</i> were made from dried jaws. Total length in fluid-preserved specimens was measured as natural total length, whereas whether reported total length in the dried jaws represented natural or stretched total length could not be confirmed.",
col.names = c("Taxon","Total Length","Est.","Lower","Upper","PE","Est.","Lower","Upper","PE","Percent Difference"))%>%
column_spec(2, italic = T)%>%
column_spec(c(3,4,8), bold = T)%>%
add_header_above(c(" "=3,"Upper Jaw Perimeter"=4,"Mouth Width"=4," "=1))%>%
kable_styling()
Taxon | Total Length | Est. | Lower | Upper | PE | Est. | Lower | Upper | PE | Percent Difference | |
---|---|---|---|---|---|---|---|---|---|---|---|
FSBC 06415 | Galeocerdo cuvieri | 362.0 | 333.8 | 264.0 | 403.7 | -8.4 | 364.1 | 240.0 | 552.4 | 0.6 | 8.3 |
FSBC 00844 | Carcharhinus leucas | 198.1 | 251.2 | 181.6 | 320.9 | 21.1 | 223.4 | 147.4 | 338.6 | 11.3 | 12.5 |
FSBC 00884 | Carcharhinus leucas | 234.9 | 237.9 | 168.2 | 307.5 | 1.2 | 244.2 | 161.1 | 370.2 | 3.8 | 2.6 |
FSBC 02127 | Galeocerdo cuvieri | 168.9 | 165.9 | 96.2 | 235.6 | -1.8 | 176.0 | 116.1 | 266.7 | 4.0 | 5.7 |
FSBC 18083 | Carcharhinus leucas | 64.0 | 122.0 | 52.1 | 191.8 | 47.5 | 78.1 | 51.5 | 118.3 | 18.0 | 56.2 |
Based on this, it seems that UJP
and mouth_width
capture similar enough morphometric signal that mouth_width
can be considered an appropriate substitute for testing whether UJP
in sharks accurately predicts body size in arthrodires (especially given UJP is unavailable for smaller sharks). The two variables disagree in the length estimates of FSBC 18083, but this is likely because this specimen pertains to a very small (possibly neonatal) Carcharhinus leucas and is outside the range of values of the dataset of Lowry et al. (2009).
5.5 Using Brachyplatystoma as a Case Study
%>%
data_mouthsfilter(genus=="Brachyplatystoma")%>%
augment(newdata=.,fit.UJP)%>%
rename(fit1.fitted=.fitted)%>%
augment(newdata=.,fit.mouthwidth)%>%
rename(fit2.fitted=.fitted)%>%
mutate(fit2.fitted=exp(fit2.fitted)*regression.stats(fit.mouthwidth)$CF)%>%
mutate(error1=100*((fit1.fitted-total_length)/total_length),
error2=100*((fit2.fitted-total_length)/total_length))%>%
select(taxon,specimen,total_length,fit1.fitted,error1,fit2.fitted,error2)%>%
kable(digits=2,align=c("l","c","c","c","c","c","c"),
col.names = c("Taxon","Specimen","Actual","Estimated","% Difference from Actual Value","Estimated","% Difference from Actual Value"),
caption="Estimated total length in <i>Brachyplatystoma capapretum</i> using upper jaw perimeter. All measurements in cm.")%>%
column_spec(1, italic = T)%>%
add_header_above(c(" "=3,"UJP"=2,"Mouth Width"=2))%>%
kable_styling()
Taxon | Specimen | Actual | Estimated | % Difference from Actual Value | Estimated | % Difference from Actual Value |
---|---|---|---|---|---|---|
Brachyplatystoma capapretum | MZUSP 78481 | 73 | 121.7 | 66.72 | 121.52 | 66.47 |
By using Brachyplatystoma capapretum, a large, nektonic fish with a superficially shark-like body shape, as a case study, it can be seen that UJP fails to accurately estimate length in this taxon, and in fact significantly over-estimates its body size (that is, B. capapretum has a much larger mouth than expected assuming shark-like proportions). This suggests that UJP
or mouth_width
may not exhibit a single allometric relationship with total length across all fishes, particularly non-sharks such as Brachyplatystoma (Siluriformes: Pimelodidae) or arthrodires.
6 Using mouth width to estimate total length in arthrodires
6.1 Mouth width versus total length in chondrichthyans (and arthrodires)
<-data_mouths%>%
(mouth_width_plotdrop_na(mouth_width)%>%
augment(fit.mouthwidth,newdata=.,interval="prediction")%>%
mutate(across(.fitted:.upper,~exp(.)*regression.stats(fit.mouthwidth)$CF),
total_length=ifelse(genus=="Dunkleosteus",
predict(fit.UJP,.),total_length),
clade2=case_when(genus=="Dunkleosteus"~"Dunkleosteus",
%in% c("Amazichthys","Newspecies")~"Est. From Skull",
genus =="Placodermi"~"Other Placodermi",
clade=="Alopias"~"Alopias",
genus=="Cladoselache"~"Cladoselache",
genus%in% c("Planonasus","Cephaloscyllium","Isistius")~
genus "Planonasus + Cephaloscyllium",
=="Chondrichthyes"~"Other Chondrichthyes"))%>%
cladefilter(clade %in% c("Placodermi","Chondrichthyes"),
!is.na(total_length)|genus=="Dunkleosteus")%>%
ggplot(.,aes(total_length,mouth_width))+
scale_x_continuous(trans="log10") + scale_y_continuous(trans="log10")+
geom_star(aes(starshape=clade2,fill=clade2),size=2)+
scale_starshape_manual(values=c(13,13,13,13,1,1,1),
labels=c("Other Chondrichthyes","*Alopias*","*Cladoselache*",
"*Plano./Cephalo./Isist.*",
"*Dunkleosteus* (Est.)","*Amazichthys*/CMNH Aspin.","Other Placodermi"),
breaks=c("Other Chondrichthyes","Alopias",
"Cladoselache",
"Planonasus + Cephaloscyllium",
"Dunkleosteus","Est. From Skull","Other Placodermi"))+
scale_fill_manual(values=c("gray","green","black","orange","yellow","magenta","black"),
breaks=c("Other Chondrichthyes","Alopias","Cladoselache",
"Planonasus + Cephaloscyllium",
"Dunkleosteus","Est. From Skull","Other Placodermi"),
na.value=NA,
labels=c("Other Chondrichthyes","*Alopias*","*Cladoselache*",
"*Plano./Cephalo./Isist.*",
"*Dunkleosteus* (Est.)","*Amazichthys*/CMNH Aspin.","Other Placodermi"))+
geom_segment(data=.%>%filter(genus %in% c("Coccosteus","Plourdosteus","Incisoscutum")),
aes(xend=total_length*0.8,yend=mouth_width*1.3))+
geom_segment(data=.%>%filter(specimen=="CMNH 5768"),
aes(xend=total_length,yend=mouth_width*0.4))+
geom_star(data=.%>%filter(clade=="Placodermi"),
aes(starshape=clade2,fill=clade2),size=3.5,show.legend=F)+
geom_line(aes(x=.fitted), color = "#3366FF",size=1.25,show.legend=F)+
geom_line(aes(x=.lower), color = "#3366FF", linetype = "dashed",show.legend=F)+
geom_line(aes(x=.upper), color = "#3366FF", linetype = "dashed",show.legend=F)+
geom_star(data=.%>%filter(clade=="Placodermi",clade2=="Est. From Skull"),size=3.5,
color="white",aes(starshape=clade2,fill=clade2),starstroke=1,show.legend=F)+
geom_star(data=.%>%filter(clade=="Placodermi",clade2=="Est. From Skull"),size=3,
color="black",aes(starshape=clade2,fill=clade2),starstroke=0.5,show.legend=F)+
geom_star(data=.%>%filter(clade=="Placodermi",clade2=="Other Placodermi"),size=3.5,
starshape=1,color="white",fill="black",starstroke=0.5,show.legend=F)+
geom_text(data=.%>%filter(genus %in% c("Coccosteus","Plourdosteus","Incisoscutum")),size=3.5,
aes(x=0.9*total_length*ifelse(genus=="Coccosteus",.85,1),
y=1.365*mouth_width*ifelse(genus=="Coccosteus",.95,1),
label=genus),hjust=1,vjust=0,fontface=3)+
geom_text(data=.%>%filter(specimen=="CMNH 5768"),size=3.5,
aes(y=0.35*mouth_width,label=genus),hjust=0.5,vjust=0,fontface=3)+
labs(x="Total Length (cm)",y="Mouth Width (cm)",starshape="Group",fill="Group")+
theme_classic()+
theme(legend.position=c(0.8,0.25),
legend.text=element_markdown()))
ggsave("Arthrodire Mouths Figure 3 (Mouth Width).pdf",mouth_width_plot,
"pdf",width=180,height=135,units="mm")
Based on this, it is clear that in all the arthrodires for which body length is directly measurable that arthrodires have much wider mouths than sharks at similar body sizes, in most cases outside the 95% prediction interval for sharks. The only sharks that plot close to arthrodires are Cephaloscyllium, Planonasus, and a few deep-sea squaloids (e.g., Isistius) that have notably large mouths relative to body size among sharks. This means that mouth dimensions are not expected to accurately predict body size in arthrodires. The estimated lengths from Ferrón are within the 95% prediction interval for sharks (and inded predict a smaller-than-average mouth for Dunkleosteus compared to sharks), but because these lengths are estimated based on a regression model derived from sharks
The two stars which are closer to the regression line formed by sharks are Amazichthys trinjasticae and an undescribed arthrodire (possibly an aspinothoracid) in the collections of the Cleveland Museum of Natural History. However, neither of these two specimens preserves the mouth, in both cases the mouth width is extrapolated from skull roof width assuming a relationship between the two similar to other arthodires. This is not the ideal way of determining mouth size in these taxa, but it’s worth noting even doing this results in mouths that are on the edge of the upper bound of the 95% prediction interval in sharks.
6.2 Testing using inner mouth width in arthrodires
%>%
data_mouthsdrop_na(mouth_width)%>%
mutate(mouth_width=ifelse(clade=="Placodermi",inner_mouth_width,mouth_width))%>%
augment(fit.mouthwidth,newdata=.,interval="prediction")%>%
mutate(across(.fitted:.upper,~exp(.)*regression.stats(fit.mouthwidth)$CF),
total_length=ifelse(genus=="Dunkleosteus",
predict(fit.UJP,.),total_length),
clade2=case_when(genus=="Dunkleosteus"~"Dunkleosteus",
%in% c("Amazichthys","Newspecies")~"Est. From Skull",
genus =="Placodermi"~"Other Placodermi",
clade=="Alopias"~"Alopias",
genus=="Cladoselache"~"Cladoselache",
genus%in% c("Planonasus","Cephaloscyllium","Isistius")~
genus "Planonasus + Cephaloscyllium",
=="Chondrichthyes"~"Other Chondrichthyes"))%>%
cladefilter(clade %in% c("Placodermi","Chondrichthyes"),
!is.na(total_length)|genus=="Dunkleosteus")%>%
ggplot(.,aes(total_length,mouth_width))+
scale_x_continuous(trans="log10") + scale_y_continuous(trans="log10")+
geom_star(aes(starshape=clade2,fill=clade2),size=2)+
scale_starshape_manual(values=c(13,13,13,13,1,1,1),
labels=c("Other Chondrichthyes","*Alopias*","*Cladoselache*",
"*Plano./Cephalo./Isist.*",
"*Dunkleosteus* (Est.)","*Amazichthys*/CMNH Aspin.","Other Placodermi"),
breaks=c("Other Chondrichthyes","Alopias",
"Cladoselache",
"Planonasus + Cephaloscyllium",
"Dunkleosteus","Est. From Skull","Other Placodermi"))+
scale_fill_manual(values=c("gray","green","black","orange","yellow","darkcyan","black"),
breaks=c("Other Chondrichthyes","Alopias","Cladoselache",
"Planonasus + Cephaloscyllium",
"Dunkleosteus","Est. From Skull","Other Placodermi"),
na.value=NA,
labels=c("Other Chondrichthyes","*Alopias*","*Cladoselache*",
"*Plano./Cephalo./Isist.*",
"*Dunkleosteus* (Est.)","*Amazichthys*/CMNH Aspin.","Other Placodermi"))+
geom_segment(data=.%>%filter(genus %in% c("Coccosteus","Plourdosteus","Incisoscutum")),
aes(xend=total_length*0.8,yend=mouth_width*1.3))+
geom_segment(data=.%>%filter(specimen=="CMNH 5768"),
aes(xend=total_length,yend=mouth_width*0.4))+
geom_star(data=.%>%filter(clade=="Placodermi"),
aes(starshape=clade2,fill=clade2),size=3.5,show.legend=F)+
geom_line(aes(x=.fitted), color = "#3366FF",size=1.25,show.legend=F)+
geom_line(aes(x=.lower), color = "#3366FF", linetype = "dashed",show.legend=F)+
geom_line(aes(x=.upper), color = "#3366FF", linetype = "dashed",show.legend=F)+
geom_star(data=.%>%filter(clade=="Placodermi",clade2=="Est. From Skull"),size=3.5,
color="white",aes(starshape=clade2,fill=clade2),starstroke=0.5,show.legend=F)+
geom_star(data=.%>%filter(clade=="Placodermi",clade2=="Other Placodermi"),size=3.5,
starshape=1,color="white",fill="black",starstroke=0.5,show.legend=F)+
geom_text(data=.%>%filter(genus %in% c("Coccosteus","Plourdosteus","Incisoscutum")),size=3.5,
aes(x=0.9*total_length*ifelse(genus=="Coccosteus",.85,1),
y=1.365*mouth_width*ifelse(genus=="Coccosteus",.95,1),
label=genus),hjust=1,vjust=0,fontface=3)+
geom_text(data=.%>%filter(specimen=="CMNH 5768"),size=3.5,
aes(y=0.35*mouth_width,label=genus),hjust=0.5,vjust=0,fontface=3)+
labs(x="Total Length (cm)",y="Mouth Width (cm)",starshape="Group",fill="Group")+
theme_classic()+
theme(legend.position=c(0.8,0.25),
legend.text=element_markdown())
Inner mouth width could only be measured for Coccosteus among arthrodires known from complete remains. Nevertheless, the pattern is similar as for when maximum mouth width is considered: Coccosteus cuspidatus is found to have a much wider mouth than sharks of similar size, whereas Dunkleosteus terrelli is found to have a much narrower (=smaller) mouth than expected for an animal of its estimated length under the length estimates of Ferrón et al. (2017).
6.3 Mouth width versus total length in osteichthyans (and arthrodires)
%>%
data_mouthsdrop_na(mouth_width)%>%
augment(fit.mouthwidth,newdata=.,interval="prediction")%>%
mutate(across(.fitted:.upper,~exp(.)*regression.stats(fit.mouthwidth)$CF),
total_length=ifelse(genus=="Dunkleosteus",
predict(fit.UJP,.),total_length),
clade2=case_when(order=="Siluriformes"~"Siluriformes",
=="Serranidae"~"Serranidae",
family=="Placodermi"~"Placodermi",
clade%in% c("Actinopterygii","Sarcopterygii")~"Other Osteichthyes"))%>%
clade filter(!is.na(total_length)|genus=="Dunkleosteus")%>%
arrange(clade2)%>%
ggplot(.,aes(total_length,mouth_width))+
scale_x_continuous(trans="log10") + scale_y_continuous(trans="log10")+
geom_star(data=.%>%filter(clade=="Chondrichthyes"),starshape=13,
fill="light gray",guide=F,show.legend=F,color="dark gray",size=2)+
geom_star(data=.%>%filter(genus=="Dunkleosteus"),starshape=1,
fill="light gray",guide=F,show.legend=F,color="dark gray",size=2)+
scale_starshape_manual(values=c(15,15,15,1),
breaks=c("Siluriformes","Serranidae","Other Osteichthyes","Placodermi","Chondrichthyes"),
na.value=NA)+
geom_line(aes(x=.fitted), color = "gray",size=1.25,show.legend=F)+
geom_line(aes(x=.lower), color = "gray", linetype = "dashed",show.legend=F)+
geom_line(aes(x=.upper), color = "gray", linetype = "dashed",show.legend=F)+
geom_star(data=.%>%filter(clade!="Chondrichthyes",genus!="Dunkleosteus"),
aes(starshape=clade2,fill=clade2),size=2)+
geom_smooth(data=.%>%filter(genus!="Dunkleosteus",clade!="Chondrichthyes"),
aes(color=clade2),formula=y~x,method="lm",se=F)+
scale_color_manual(values=c(hue_pal()(3),NA),
breaks=c("Siluriformes","Serranidae","Other Osteichthyes","Placodermi"),
na.value=NA)+
scale_fill_manual(values=c(hue_pal()(3),"black"),
breaks=c("Siluriformes","Serranidae","Other Osteichthyes","Placodermi"),
na.value=NA)+
geom_segment(data=.%>%filter(genus %in% c("Coccosteus","Plourdosteus","Incisoscutum")),
aes(xend=total_length*0.8,yend=mouth_width*1.3))+
geom_star(data=.%>%filter(clade=="Placodermi",genus!="Dunkleosteus"),size=3.5,
starshape=1,color="white",fill="black",starstroke=0.5)+
geom_text(data=.%>%filter(genus %in% c("Coccosteus","Plourdosteus","Incisoscutum")),
aes(x=0.9*total_length*ifelse(genus=="Coccosteus",.85,1),
y=1.365*mouth_width*ifelse(genus=="Coccosteus",.95,1),
label=genus),hjust=1,vjust=0,fontface=3)+
labs(x="Total Length (cm)",y="Mouth Width (cm)",starshape="Group",fill="Group",color="Group")+
theme_classic()+
theme(legend.position=c(0.8,0.2))
By focusing on the relationship between mouth width and total length in all fishes (i.e., adding osteichthyans into consideration), it is clear that the relationship between mouth width and total length is not as consistent as is seen in sharks. In fact, arthrodires show mouth-body proportions that are very similar to extant predatory catfishes (Siluriformes).
6.4 Error in using mouth proportions in sharks to estimate length in complete arthrodires
%>%
fossil_taxa_mouthsfilter(clade=="Placodermi")%>%
drop_na(total_length,mouth_width)%>%
augment(fit.mouthwidth,newdata=.)%>%
mutate(.fitted=exp(.fitted)*regression.stats(fit.mouthwidth)$CF)%>%
mutate(error=100*(total_length-.fitted)/.fitted)%>%
mutate(taxon=ifelse(genus=="Newspecies","CMNH aspinothoracid",taxon))%>%
add_row(taxon="All Species",error=mean(.$error))%>%
select(taxon,specimen,total_length,.fitted,error)%>%
kable(digits=c(1,1,1,1,1),col.names=c("Taxon","Specimen","Total Length","Est. Length","PE"),
caption="Percent error when estimating total length in complete specimens of arthrodires using mouth width.",
align=c("l","c","c","c","c"))%>%
row_spec(9, bold = T)%>%
kable_styling()
Taxon | Specimen | Total Length | Est. Length | PE |
---|---|---|---|---|
Amazichthys trinajsticae | AA.MEM.DS.8 | 89.7 | 131.3 | -31.7 |
Coccosteus cuspidatus | Recon. (M & W 1968) | 39.4 | 89.1 | -55.8 |
Holonema westolli | Recon. (Miles 1971) | 60.6 | 134.5 | -54.9 |
Incisoscutum ritchei | Recon. (Trinjastic 2013) | 30.3 | 52.6 | -42.4 |
Millerosteus minor | Composite Millerosteus | 14.9 | 31.1 | -51.9 |
CMNH aspinothoracid | CMNH 50233 | 63.0 | 105.6 | -40.3 |
Plourdosteus canadensis | MNHM 2-177 | 37.5 | 103.6 | -63.8 |
Watsonosteus fletti | NMS G.1995.4.2 | 56.6 | 144.8 | -60.9 |
All Species | NA | NA | NA | -50.2 |
6.5 Estimating mouth size in arthrodires like Coccosteus assuming similar proportions to sharks
<-
fit.total_length_to_mouth_widthlm(log(mouth_width)~log(total_length),data_mouths%>%
filter(clade=="Chondrichthyes",
!order %in% c("Chimaeriformes","Rajiformes"),
!="Alopias"))
genus%>%
data_mouthsdrop_na(mouth_width,total_length)%>%
filter(clade=="Placodermi",
!genus %in% c("Amazichthys","Newspecies"))%>%
augment(newdata=.,fit.total_length_to_mouth_width)%>%
mutate(.fitted=exp(.fitted)*regression.stats(fit.total_length_to_mouth_width)$CF,
diff=100*(.fitted-mouth_width)/.fitted)%>%
select(taxon,specimen,mouth_width,.fitted,diff)%>%
arrange(mouth_width)%>%
kable(digits=2,align=c("l","c","c","c","c"),
col.names = c("Taxon","Specimen","Actual","Estimated","% Diff."),
caption="Estimated mouth width in arthrodire taxa of known total length using a model based on extant sharks (excluding <i>Alopias</i>). Note that <i>Holonema</i> and <i>Watsonosteus</i> are based off of dorsoventrally crushed specimens but <i>Incisoscutum</i>, <i>Coccosteus</i>, and <i>Plourdosteus</i> are based off of three-dimensional specimens or reconstructions. All measurements in cm.")%>%
add_header_above(c(" "=2,"Mouth Width"=3))%>%
column_spec(1, italic = T)%>%
kable_styling()
Taxon | Specimen | Actual | Estimated | % Diff. |
---|---|---|---|---|
Millerosteus minor | Composite Millerosteus | 1.89 | 1.00 | -88.25 |
Incisoscutum ritchei | Recon. (Trinjastic 2013) | 3.60 | 2.20 | -63.27 |
Coccosteus cuspidatus | Recon. (M & W 1968) | 6.87 | 2.96 | -132.29 |
Plourdosteus canadensis | MNHM 2-177 | 8.27 | 2.80 | -195.34 |
Holonema westolli | Recon. (Miles 1971) | 11.38 | 4.78 | -138.02 |
Watsonosteus fletti | NMS G.1995.4.2 | 12.46 | 4.43 | -181.17 |
If reversing the consideration and trying to estimate mouth width in arthrodires based on known total length, arthrodires are predicted to have mouths less than half their actual width. This is particularly pronounced in Coccosteus, Incisoscutum, and Plourdosteus, where the mouths can be measured from 3D specimens or reconstructions and are not subject to dorsoventral crushing.
%>%
data_mouthsselect(-mouth_width)%>%
rename(mouth_width=inner_mouth_width)%>%
drop_na(mouth_width,total_length)%>%
augment(newdata=.,fit.total_length_to_mouth_width)%>%
mutate(.fitted=exp(.fitted)*regression.stats(fit.total_length_to_mouth_width)$CF,
diff=100*(.fitted-mouth_width)/.fitted)%>%
select(taxon,specimen,mouth_width,.fitted,diff)%>%
arrange(mouth_width)%>%
kable(digits=2,align=c("l","c","c","c","c"),
col.names = c("Taxon","Specimen","Actual","Estimated","% Diff."),
caption="Estimated mouth width in arthrodire taxa of known total length using a model based on extant sharks and inner mouth width. All measurements in cm.")%>%
add_header_above(c(" "=2,"Mouth Width"=3))%>%
column_spec(1, italic = T)%>%
kable_styling()
Taxon | Specimen | Actual | Estimated | % Diff. |
---|---|---|---|---|
Coccosteus cuspidatus | Recon. (M & W 1968) | 6.10 | 2.96 | -106.19 |
Plourdosteus canadensis | MNHM 2-177 | 7.82 | 2.80 | -179.27 |
7 Estimating the length of arthrodires using approximated UJP
<-lm(log(total_length)~log(UJP),
fit.approx_UJP_old%>% drop_na(mouth_length) %>% filter(clade=="Chondrichthyes") %>%
data_mouths mutate(UJP=ramanujan.approx(mouth_length*2,mouth_width)/2))
<-lm(log(total_length)~log(UJP),
fit.approx_UJP%>% drop_na(mouth_length) %>% filter(clade=="Chondrichthyes") %>%
data_mouths filter(!genus %in% c("Cetorhinus","Rhincodon","Megachasma","Alopias"),
%in% c("Lamniformes","Carcharhiniformes","Hexanchiiformes")) %>%
order mutate(UJP=ramanujan.approx(mouth_length*2,mouth_width)/2))
Summary of model including all taxa
summary(fit.approx_UJP_old)
##
## Call:
## lm(formula = log(total_length) ~ log(UJP), data = data_mouths %>%
## drop_na(mouth_length) %>% filter(clade == "Chondrichthyes") %>%
## mutate(UJP = ramanujan.approx(mouth_length * 2, mouth_width)/2))
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.80346 -0.16582 -0.04366 0.13669 0.83162
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 2.60612 0.03802 68.55 <2e-16 ***
## log(UJP) 0.78160 0.01490 52.47 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.2626 on 446 degrees of freedom
## (30 observations deleted due to missingness)
## Multiple R-squared: 0.8606, Adjusted R-squared: 0.8603
## F-statistic: 2753 on 1 and 446 DF, p-value: < 2.2e-16
Summary of model including only Carcharhiniformes, Lamniformes, and Hexanchiiformes
summary(fit.approx_UJP)
##
## Call:
## lm(formula = log(total_length) ~ log(UJP), data = data_mouths %>%
## drop_na(mouth_length) %>% filter(clade == "Chondrichthyes") %>%
## filter(!genus %in% c("Cetorhinus", "Rhincodon", "Megachasma",
## "Alopias"), order %in% c("Lamniformes", "Carcharhiniformes",
## "Hexanchiiformes")) %>% mutate(UJP = ramanujan.approx(mouth_length *
## 2, mouth_width)/2))
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.49370 -0.11888 -0.02922 0.09438 0.66242
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 2.44705 0.03519 69.54 <2e-16 ***
## log(UJP) 0.83849 0.01428 58.71 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1975 on 314 degrees of freedom
## (22 observations deleted due to missingness)
## Multiple R-squared: 0.9165, Adjusted R-squared: 0.9162
## F-statistic: 3447 on 1 and 314 DF, p-value: < 2.2e-16
Regression statistics
rbind("All Taxa"=regression.stats(fit.approx_UJP),
"Carcharhiniformes, Lamniformes, Hexanchiiformnes"=regression.stats(fit.approx_UJP))
par(mfrow=c(1,2))
plot(lm(total_length~UJP,
%>%
data_mouths drop_na(mouth_length) %>% filter(clade=="Chondrichthyes") %>%
mutate(UJP=ramanujan.approx(mouth_length*2,mouth_width)/2)),
3)
plot(fit.approx_UJP_old,3)
%>%
data_mouthsdrop_na(mouth_length,mouth_width) %>%
filter(clade=="Chondrichthyes") %>%
mutate(UJP=ramanujan.approx(mouth_length*2,mouth_width)/2,
clade2=case_when(genus == "Alopias" ~ "Alopias",
== "Squaliformes" ~ "Squaliformes",
order == "Orectolobiformes" ~ "Orectolobiformes",
order == "Chimaeriformes" ~ "Chimaeriformes",
order == "Rhinopristiformes" ~ "Rhinopristiformes",
order %in% c("Megachasma","Cetorhinus","Rhincodon") ~ "Filter-Feeding Sharks",
genus TRUE ~ "Other Taxa"))%>%
mutate(clade2=factor(clade2,ordered=T,levels=c("Alopias",
"Filter-Feeding Sharks",
"Chimaeriformes",
"Orectolobiformes",
"Rhinopristiformes",
"Squaliformes",
"Other Taxa")))%>%
augment(fit.approx_UJP_old,newdata=.)%>%
ggplot(aes(.fitted,.resid)) +
geom_hline(yintercept=0,linetype="dotted",color="light grey") +
geom_point(aes(fill=clade2,shape=clade2)) +
geom_smooth(method="loess",formula=y~x,color="red",se=F,size=0.5) +
scale_shape_manual(values=c(22,22,24,24,24,24,21))+
scale_fill_manual(values=c(hue_pal()(6),"grey"))+
theme_classic()+
labs(x="Fitted Values",fill="Clade",shape="Clade",y="Residuals")+
theme(legend.position="bottom")
plot(fit.approx_UJP,1)
7.1 Testing how closely estimated UJP matches actual UJP in FSBC Sharks
#A separate equation was called for using estimated jaw perimeter rather than actual, as otherwise R freaks out if you try to change an existing equation to use a new variable.
<-lm(total_length ~ perimeter_est,lowry_sharks %>% mutate(perimeter_est=UJP))
lowry_approx
%>%
fsbc_sharksmutate(perimeter_est=ramanujan.approx(mouth_length*2,mouth_width)/2)%>%
mutate(fit_ujp=predict(fit.UJP,.,interval="prediction")[,1],
lwr_ujp=predict(fit.UJP,.,interval="prediction")[,2],
upr_ujp=predict(fit.UJP,.,interval="prediction")[,3],
PI_ujp=paste0("(",round(lwr_ujp,1),"–",round(upr_ujp,1),")"),
PE_ujp=((fit_ujp-total_length)/fit_ujp)*100,
fit_mouth=exp(predict(fit.mouthwidth,.,interval="prediction")[,1]),
lwr_mouth=exp(predict(fit.mouthwidth,.,interval="prediction")[,2]),
upr_mouth=exp(predict(fit.mouthwidth,.,interval="prediction")[,3]),
PI_mouth=paste0("(",round(lwr_mouth,1),"–",round(upr_mouth,1),")"),
PE_mouth=((fit_mouth-total_length)/fit_mouth)*100,
fit_approx=predict(lm(total_length ~ perimeter_est,lowry_sharks %>% mutate(perimeter_est=UJP)),
interval="prediction")[,1],
.,lwr_approx=predict(lm(total_length ~ perimeter_est,lowry_sharks %>% mutate(perimeter_est=UJP)),
interval="prediction")[,2],
.,upr_approx=predict(lm(total_length ~ perimeter_est,lowry_sharks %>% mutate(perimeter_est=UJP)),
interval="prediction")[,3],
.,PI_approx=paste0("(",round(lwr_approx,1),"–",round(upr_approx,1),")"),
PE_approx=((fit_approx-total_length)/fit_approx)*100)%>%
column_to_rownames("specimen")%>%
mutate(est_diff_mouth=100*abs(fit_ujp-fit_mouth)/fit_mouth,
est_diff_approx=100*abs(fit_ujp-fit_approx)/fit_approx)%>%
select(taxon,total_length,
UJP,fit_ujp,PI_ujp,PE_ujp,
mouth_width,fit_mouth,PI_mouth,PE_mouth,est_diff_mouth,%>%
perimeter_est,fit_approx,PI_approx,PE_approx,est_diff_approx)kable(digits=1,
align=c("l","c","c","c","c","c","c","c","c","c","c","c","c","c","c"),
caption="Testing how closely Ramanujan's approximation of elliptical perimeter. approximates UJP in dried jaws of sharks. PE is error relative to measured total length and percent difference is difference relative to UJP-derived estimate. All lengths in cm.",
col.names = c("Taxon","Total Length",
"Value","Est.","95% P.I.","PE",
"Value","Est.","95% P.I.","PE","Percent Difference",
"Value","Est.","95% P.I.","PE","Percent Difference"))%>%
column_spec(2, italic = T)%>%
column_spec(c(4,13), bold = T)%>%
add_header_above(c(" "=3,"Upper Jaw Perimeter"=4,"Mouth Width"=5,"Approximated UJP"=5))%>%
kable_styling() %>%
scroll_box(width = "100%")
Taxon | Total Length | Value | Est. | 95% P.I. | PE | Value | Est. | 95% P.I. | PE | Percent Difference | Value | Est. | 95% P.I. | PE | Percent Difference | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
FSBC 06415 | Galeocerdo cuvieri | 362.0 | 53.5 | 333.8 | (264–403.7) | -8.4 | 39.5 | 364.1 | (240–552.4) | 0.6 | 8.3 | 60.1 | 368.9 | (298.8–438.9) | 1.9 | 9.5 |
FSBC 00844 | Carcharhinus leucas | 198.1 | 38.0 | 251.2 | (181.6–320.9) | 21.1 | 21.7 | 223.4 | (147.4–338.6) | 11.3 | 12.5 | 36.6 | 244.0 | (174.4–313.7) | 18.8 | 3.0 |
FSBC 00884 | Carcharhinus leucas | 234.9 | 35.5 | 237.9 | (168.2–307.5) | 1.2 | 24.2 | 244.2 | (161.1–370.2) | 3.8 | 2.6 | 37.5 | 248.8 | (179.1–318.4) | 5.6 | 4.4 |
FSBC 02127 | Galeocerdo cuvieri | 168.9 | 22.0 | 165.9 | (96.2–235.6) | -1.8 | 16.2 | 176.0 | (116.1–266.7) | 4.0 | 5.7 | 23.7 | 175.0 | (105.3–244.7) | 3.5 | 5.2 |
FSBC 18083 | Carcharhinus leucas | 64.0 | 13.8 | 122.0 | (52.1–191.8) | 47.5 | 6.0 | 78.1 | (51.5–118.3) | 18.0 | 56.2 | 14.0 | 123.1 | (53.3–193) | 48.0 | 1.0 |
7.2 Comparing estimated UJP to actual UJP in arthrodires
%>%
data_mouths filter(clade=="Placodermi") %>%
drop_na(UJP) %>%
mutate(UJP2=ramanujan.approx(mouth_length,mouth_width)/2,
UJP3=c(NA,116,55,84,100),
ratio=UJP2/UJP) %>%
select(taxon,specimen, UJP, UJP3, UJP2, ratio) %>%
kable(digits=2,align=c("l","c","c","c","c","c"),
col.names=c("Taxon","Specimen","Actual UJP (Ferrón)","Actual UJP (Measured by Author)","Estimated UJP (Ramanujan Approximation)","Ratio"),
caption="Comparison of estimated UJP to directly measured UJP in arthrodires. Ratio is the ratio between the approximated UJP and the measurements reported in Ferrón et al. (2017)") %>%
column_spec(1,italic = T) %>%
kable_styling()
Taxon | Specimen | Actual UJP (Ferrón) | Actual UJP (Measured by Author) | Estimated UJP (Ramanujan Approximation) | Ratio |
---|---|---|---|---|---|
Coccosteus cuspidatus | Recon. (M & W 1968) | 9.78 | NA | 7.17 | 0.73 |
Dunkleosteus terrelli | CMNH 5768 | 120.00 | 116 | 88.85 | 0.74 |
Dunkleosteus terrelli | CMNH 7424 | 51.00 | 55 | 38.30 | 0.75 |
Dunkleosteus terrelli | CMNH 6090 | 91.00 | 84 | 64.89 | 0.71 |
Dunkleosteus terrelli | CMNH 7054 | 99.00 | 100 | 67.67 | 0.68 |
Ramanujan’s approximation does not accurately estimate UJP in arthrodires, in contrast to sharks. This is likely because the skulls and mouths of arthrodires are blockier and more rectangular compared to the jaw cartilages of sharks, and thus their UJP cannot be approximated as an idealized ellipse. The ratio of actual UJP to estimated UJP is similar in both Dunkleosteus and Coccosteus, suggesting that UJP has been measured/estimated correctly and the difference is due to actual differences in the skull shape of arthrodires.
Measurements of UJP on specimens taken by the present author on specimens of Dunkleosteus are similar to the values reported in Ferrón et al. (2017), suggesting the smaller UJPs predicted by Ramanujan’s approximation cannot be attributed to measurement error. Differences between Ferrón et al. (2017)’s measurements and the author’s are probably due to measurement error from the difficulties in consistently placing a tape measurer along the UJP of mounted specimens, especially as UJP is not a perimeter along a well-defined edge but a detour must be made to encompass the upper supragnathals. One of the staff members at the Cleveland Museum of Natural History (A. McGee), was involved in the collection of UJP for both studies, and discussions with A. McGee suggest the two measurements were fairly close.
7.3 Length estimates in arthrodires using estimated UJP
%>% filter(clade=="Placodermi") %>% drop_na(UJP) %>%
data_mouths arrange(mouth_width) %>%
augment(fit.approx_UJP_old,newdata=.,interval="predict") %>%
mutate(across(.fitted:.upper,~exp(.)*regression.stats(fit.approx_UJP_old)$CF)) %>%
rename_at(vars(starts_with('.')), funs(paste0("fit1",.)))%>%
augment(fit.approx_UJP,newdata=.,interval="predict") %>%
rename_at(vars(starts_with('.')), funs(paste0("fit2",.)))%>%
mutate(across(fit2.fitted:fit2.upper,~exp(.)*regression.stats(fit.approx_UJP)$CF),
fit_ferron=predict(fit.UJP,.),
fit1.range=paste0("(",round(fit1.lower,1),"–",round(fit1.upper,1),")"),
fit2.range=paste0("(",round(fit2.lower,1),"–",round(fit2.upper,1),")"))%>%
mutate(PE1=100*(fit1.fitted-fit_ferron)/fit1.fitted,
PE2=100*(fit2.fitted-fit_ferron)/fit2.fitted) %>%
select(taxon,specimen,
fit1.fitted,fit1.range,PE1,%>%
fit2.fitted,fit2.range,PE2) kable(caption="Estimated length of arthrodires using UJP and estimated UJP from a broader sample of sharks",
digits=1,
align=c("l","c","c","c","c","c","c","c"),
col.names = c("Taxon","Specimen",
"Est.","95% P.I.","PE",
"Est.","95% P.I.","PE"))%>%
add_header_above(c(" "=2,"Using All Sharks"=3,"Predatory Carcharhiniformes, Lamniformes, and Hexanchiiformes Only"=3))%>%
column_spec(1, italic = T)%>%
kable_styling()
Taxon | Specimen | Est. | 95% P.I. | PE | Est. | 95% P.I. | PE |
---|---|---|---|---|---|---|---|
Coccosteus cuspidatus | Recon. (M & W 1968) | 83.1 | (49.6–139.3) | -21.3 | 79.8 | (54–117.7) | -26.4 |
Dunkleosteus terrelli | CMNH 7424 | 302.1 | (179.9–507.4) | -6.1 | 318.5 | (215.3–471.3) | -0.6 |
Dunkleosteus terrelli | CMNH 6090 | 475.0 | (282.3–799.1) | -12.4 | 517.6 | (349.1–767.5) | -3.1 |
Dunkleosteus terrelli | CMNH 7054 | 507.3 | (301.5–853.8) | -13.6 | 555.5 | (374.5–824) | -3.8 |
Dunkleosteus terrelli | CMNH 5768 | 589.6 | (350.1–993) | -16.7 | 652.7 | (439.6–969.1) | -5.5 |
%>%
data_mouthsdrop_na(mouth_length,mouth_width) %>%
filter(genus=="Cladoselache") %>%
mutate(UJP=ramanujan.approx(mouth_length*2,mouth_width)/2)%>%
augment(fit.approx_UJP_old,newdata=.,interval="predict") %>%
mutate(across(.fitted:.upper,~exp(.)*regression.stats(fit.approx_UJP_old)$CF)) %>%
rename_at(vars(starts_with('.')), funs(paste0("fit1",.)))%>%
augment(fit.approx_UJP,newdata=.,interval="predict") %>%
rename_at(vars(starts_with('.')), funs(paste0("fit2",.)))%>%
mutate(across(fit2.fitted:fit2.upper,~exp(.)*regression.stats(fit.approx_UJP)$CF),
fit_ferron=predict(fit.UJP,.),
fit1.range=paste0("(",round(fit1.lower,1),"–",round(fit1.upper,1),")"),
fit2.range=paste0("(",round(fit2.lower,1),"–",round(fit2.upper,1),")"))%>%
mutate(PE1=100*(fit1.fitted-total_length)/fit1.fitted,
PE2=100*(fit2.fitted-total_length)/fit2.fitted) %>%
select(taxon,specimen,total_length,
fit1.fitted,fit1.range,PE1,%>%
fit2.fitted,fit2.range,PE2) kable(caption="Estimated length of *Cladoselache* using estimated UJP. PE represents error relative to measured total length",
digits=c(1,1,1,1,1,2,1,1,2),
align=c("l","c","c","c","c","c","c","c","c"),
col.names = c("Taxon","Specimen","Total Length",
"Est.","95% P.I.","PE",
"Est.","95% P.I.","PE"))%>%
add_header_above(c(" "=3,"Using All Sharks"=3,"Predatory Carcharhiniformes, Lamniformes, and Hexanchiiformes Only"=3))%>%
column_spec(1, italic = T)%>%
kable_styling()
Taxon | Specimen | Total Length | Est. | 95% P.I. | PE | Est. | 95% P.I. | PE |
---|---|---|---|---|---|---|---|---|
Cladoselache sp. | AMNH 240 | 60.5 | 92.6 | (55.2–155.1) | 34.62 | 89.5 | (60.7–132.1) | 32.41 |
Cladoselache sp. | CMNH 5934 | 86.0 | 129.1 | (77–216.5) | 33.39 | 128.0 | (86.7–188.9) | 32.79 |
Cladoselache sp. | CMNH 5047 | 154.0 | 183.2 | (109.2–307.3) | 15.93 | 186.2 | (126.1–275.1) | 17.31 |
7.4 Scatterplot of UJP versus total length
ggplot(data_mouths %>%
mutate(UJP=ramanujan.approx(mouth_length*2,mouth_width)/2,
clade=ifelse(clade %in% c("Actinopterygii","Sarcopterygii"),"Osteichthyes",clade)) %>%
drop_na(UJP,total_length) %>%
group_by(clade),
aes(total_length,UJP)) +
geom_star(data=.%>%filter(clade=="Osteichthyes"),aes(starshape=clade,fill=clade,color=clade)) +
geom_star(data=.%>%filter(clade=="Chondrichthyes"),aes(starshape=clade,fill=clade,color=clade)) +
geom_segment(data=.%>%filter(genus=="Coccosteus"),
aes(y=UJP,yend=UJP+4,x=total_length,xend=total_length-24),alpha=0.75)+
geom_star(data=.%>%filter(clade=="Placodermi"),aes(starshape=clade,fill=clade,color=clade)) +
geom_star(data=.%>%filter(clade=="Placodermi"),aes(starshape=clade,fill=clade,color=clade),size=2.5,show.legend=F) +
scale_color_manual(values=c("black","dark grey","black"))+
scale_fill_manual(values=c(hue_pal()(1),"light grey","white"))+
scale_starshape_manual(values=c(13,15,1))+
geom_text(data=. %>% filter(genus=="Coccosteus"),hjust=1,fontface=3,
aes(label=genus,x=total_length-25,y=UJP+5))+
scale_x_continuous(trans="log10") +
scale_y_continuous(trans="log10") +
labs(x="Total Length (cm)",y="Estimated Upper Jaw Perimeter (cm)",
starshape="Clade",fill="Clade",color="Clade")+
theme(legend.position = c(0.8,0.2))
7.5 Relative size of UJP in Coccosteus
%>%
data_mouths mutate(UJP=ifelse(is.na(UJP),
ramanujan.approx(mouth_length*2,mouth_width)/2,
%>%
UJP)) drop_na(UJP) %>%
group_by(taxon) %>%
summarise(UJP=mean(UJP),clade=unique(clade),total_length=mean(total_length)) %>%
mutate(`UJP/total_length`=UJP/total_length) %>%
arrange(`UJP/total_length`) %>%
filter(`UJP/total_length` < 0.275 & `UJP/total_length` > 0.225) %>%
select(taxon,clade,`UJP/total_length`) %>%
kable(col.names = c("Taxon","Clade","UJP/Total Length"),digits=3,
caption="Proportional UJP in *Coccosteus* compared with taxa of similar estimated UJP")%>%
column_spec(1,italic=T) %>%
kable_styling()
Taxon | Clade | UJP/Total Length |
---|---|---|
Epinephelus itajara | Actinopterygii | 0.226 |
Lepomis cyanellus | Actinopterygii | 0.226 |
Neogobius melanostomus | Actinopterygii | 0.231 |
Amia calva | Actinopterygii | 0.232 |
Lepisosteus oculatus | Actinopterygii | 0.233 |
Etmopterus spinax | Chondrichthyes | 0.233 |
Lutjanus cyanopterus | Actinopterygii | 0.233 |
Heteropriacanthus cruentatus | Actinopterygii | 0.236 |
Acanthocybium solandri | Actinopterygii | 0.236 |
Thunnus atlanticus | Actinopterygii | 0.236 |
Polyprion americanus | Actinopterygii | 0.238 |
Sander vitreum | Actinopterygii | 0.238 |
Sander canadense | Actinopterygii | 0.239 |
Pomoxis annularis | Actinopterygii | 0.239 |
Salvelinus namaycush | Actinopterygii | 0.241 |
Esox masquinongy | Actinopterygii | 0.242 |
Oncorhynchus mykiss | Actinopterygii | 0.244 |
Oncorhynchus kisutch | Actinopterygii | 0.246 |
Coccosteus cuspidatus | Placodermi | 0.248 |
Beryx decadactylus | Actinopterygii | 0.249 |
Micropterus dolomieu | Actinopterygii | 0.250 |
Calamus bajonado | Actinopterygii | 0.250 |
Megachasma pelagios | Chondrichthyes | 0.257 |
Scombrops oculatus | Actinopterygii | 0.258 |
Micropterus salmoides | Actinopterygii | 0.259 |
Salvelinus fontinalis | Actinopterygii | 0.262 |
Latimeria chalumnae | Sarcopterygii | 0.262 |
Mycteroperca venenosa | Actinopterygii | 0.263 |
Epinephelus morio | Actinopterygii | 0.263 |
Oncorhynchus clarkii | Actinopterygii | 0.266 |
Brotula barbata | Actinopterygii | 0.267 |
Tylosurus crocodilus | Actinopterygii | 0.267 |
Epinephelus drummondhayi | Actinopterygii | 0.268 |
Hexanchus griseus | Chondrichthyes | 0.270 |
Mycteroperca interstitialis | Actinopterygii | 0.271 |
8 Diagnostic plots for UJP and mouth width
8.1 UJP
par(mfrow=c(2,2))
plot(fit.UJP)
Based on this UJP shows some slight heteroskedasticity, and the residuals seem to be slightly non-normally distributed.
8.2 Mouth Width
par(mfrow=c(2,2))
plot(fit.mouthwidth)
9 Plotting against head length
<-data_mouths%>%
data_mouthsmutate(total_length=ifelse(genus!="Dunkleosteus",
total_length,predict(fit.UJP,.)))
ggplot(data_mouths %>%
drop_na(head_length,total_length,shape)%>%
filter(clade %in% c("Actinopterygii","Sarcopterygii",
"Placodermi","Chondrichthyes"))%>%
mutate(percent_head_length=head_length/total_length),
aes(total_length,head_length/total_length))+
geom_star(aes(starshape=clade,fill=shape))+
scale_starshape_manual(values=c(15,13,1,28))+
geom_star(data=. %>% filter(clade=="Placodermi",genus!="Dunkleosteus"),
starshape=1,size=3.5,color="white",fill="black",starstroke=0.5)+
geom_hline(yintercept=0.17,linetype="dashed")+
geom_star(data=. %>% filter(genus=="Dunkleosteus"),
starshape=1,size=3.5,fill="yellow")+
annotate(geom="text",x=5,y=0.16,label="Eel-Like Taxa")+
annotate(geom="text",x=480,y=0.085,hjust=1,label="Dunkleosteus",fontface=3)+
annotate(geom="text",x=975,y=0.06,hjust=1,label="Regalecus",fontface=3)+
scale_fill_manual(values=c(hue_pal()(5),"gray"))+
scale_x_continuous(trans="log10")+
scale_y_continuous(labels=scales::percent_format(accuracy=1))+
labs(x="Total Length (cm)",y="Percent Head Length",fill="Body Shape",starshape="Clade")+
theme_classic()+
guides(fill=guide_legend(nrow=2,override.aes = list(starshape=15)),
starshape=guide_legend(nrow=2))+
theme(legend.position="bottom",legend.box = "horizontal")
Plotting head length as a percent of total length results in Dunkleosteus (using the estimates of Ferrón et al. 2017) plotting far outside the morphospace formed by almost all living fishes. Notably, other arthrodires do not show head-body proportions similar to the estimated values for Dunkleosteus by Ferrón et al. (2017), instead they plot well within the range of variation of extant fusiform fishes. Holonema and Amazichthys plot among extant taxa with elongate trunks (e.g., Coryphaena, Cheirocentrus, some gempylids, etc.), but still do not show proportions as extreme as Ferrón et al. (2017) implies for Dunkleosteus.
9.1 Highlighting taxa with elongate trunks
<-ggplot(
dunkleosteus_percent_head%>%
data_mouths drop_na(head_length,total_length)%>%
mutate(percent_head_length=head_length/total_length,
elongate=ifelse(shape %in% c("anguilliform","macruriform")|
%in% c("Cheirocentrus","Coryphaena","Tetrapturus",
genus "Polypterus","Alepisaurus","Gonorynchus",
"Rhaphiodon",
"Thyrsitoides","Gempylus","Thyrsites")|
%in% "Belonidae",
family "Elongate Postcranium","Not Elongate"))%>%
arrange(elongate),
aes(total_length,head_length/total_length))+
geom_segment(data=.%>%filter(specimen=="CMNH 6090"),
aes(xend=total_length*0.8,yend=0.9*head_length/total_length),color="black")+
geom_segment(data=.%>%filter(genus=="Regalecus",total_length==367),
aes(xend=1250,yend=percent_head_length-0.001))+
geom_star(aes(starshape=clade,fill=elongate))+
geom_star(data=.%>%filter(elongate=="Elongate Postcranium"),
aes(starshape=clade,fill=elongate))+
scale_starshape_manual(values=c(15,13,1,28,11))+
geom_segment(aes(x=70.65,y=0.1554,xend=1250,yend=0.16),size=0.4)+
geom_segment(aes(x=71.4,y=0.2803,xend=1250,yend=0.325),size=0.4)+
geom_segment(aes(x=96.8,y=0.2278,xend=1250,yend=0.24),size=0.4)+
geom_star(data=.%>%
filter(genus=="Coryphaena"&total_length==70.65|
=="Epinephelus_malabaricus"&total_length==71.4|
taxon=="Ruvettus"&total_length==96.8),
genusaes(starshape=clade,fill=elongate))+
geom_star(data=.%>%filter(clade=="Placodermi"),starshape=1,size=4,
color="white",fill="black")+
geom_hline(yintercept=0.17,linetype="dashed")+
geom_star(data=. %>% filter(genus=="Dunkleosteus"),
starshape=1,size=4,fill="yellow",color="black")+
annotate(geom="text",x=2,y=0.16,size=3,label="Eel-Like Taxa")+
annotate(geom="text",x=480,y=0.08,hjust=1,label="Dunkleosteus",
size=3,fontface=3)+
annotate(geom="text",x=4350,y=0.035,hjust=1,label="Regalecus",
size=3,fontface=3)+
annotate(geom="text",x=4350,y=0.14,hjust=1,label="Coryphaena",
size=3,fontface=3)+
annotate(geom="text",x=4350,y=0.22,hjust=1,label="Ruvettus",
size=3,fontface=3)+
annotate(geom="text",x=4350,y=0.305,hjust=1,label="Epinephelus",
size=3,fontface=3)+
coord_cartesian(xlim=c(1,2900),ylim=c(0.04,0.39))+
scale_x_continuous(trans="log10")+
scale_y_continuous(labels=scales::percent_format(accuracy=1))+
labs(x="Total Length (cm)",y="Percent Head Length",fill="Body Shape",starshape="Clade")+
theme_cowplot()+
guides(fill=guide_legend(nrow=2,override.aes = list(starshape=15)),
starshape=guide_legend(ncol=2,override.aes = list(fill="light gray")))+
theme(legend.position="bottom",
legend.text=element_text(size=9),
legend.title=element_text(size=10))
<-ggdraw(dunkleosteus_percent_head) +
(dunkleosteus_percent_head_regalecusdraw_image("Arthrodire Mouths Supplementary Figure 4 (Epinephelus).png",
x=0.415,y=0.335,scale=0.15)+
draw_image("Arthrodire Mouths Supplementary Figure 2 (Coryphaena).png",
x=0.415,y=-.01,scale=0.15)+
draw_image("Arthrodire Mouths Supplementary Figure 3 (Ruvettus).png",
x=0.415,y=.155,scale=0.15)+
draw_image("Arthrodire Mouths Supplementary Figure 1 (Regalecus).png",
x=0.415,y=-.195,scale=0.15))
ggsave("Arthrodire Mouths Figure 5 (Percent Head Dunkleosteus).pdf",
device="pdf",
dunkleosteus_percent_head_regalecus,units="mm",width=165,height=130)
In fact, the estimates from Ferrón et al. (2017) result in Dunkleosteus plotting in a region of morphospace only occupied by highly elongate fish. Indeed, the results of Ferrón et al. (2017) suggest head-body proportions that are more extreme than the majority of most elongate-bodied fishes, even moreso than groups such as Anguilliformes. The only extant fishes which show proportions comparable to these inferred proportions are Electrophorus and Regalecus, making it highly unlikely that Dunkleosteus was as long as predicted by Ferrón et al. (2017) or many previous studies on Dunkleosteus (as even most smaller estimates in previous studies for D. terrelli would still result in this taxon plotting among Anguilliformes and similar taxa).
9.2 Using precaudal length
Precaudal length for Dunkleosteus terrelli was calculated by taking the length of the upper lobe of the caudal fin from Ferrón et al. (2017), multiplying by the cosine to calculate the anteroposterior length of the fin in natural position, and then subtracting that from the total length.
ggplot(data_mouths %>%
drop_na(shape)%>%
filter(total_length!=precaudal_length|genus=="Dunkleosteus")%>%
mutate(percent_head_length=head_length/precaudal_length),
aes(precaudal_length,head_length/precaudal_length))+
geom_star(aes(starshape=clade,fill=shape))+
scale_starshape_manual(values=c(15,13,1,28))+
geom_star(data=.%>%filter(clade=="Placodermi",genus!="Dunkleosteus"),starshape=1,size=5.5,color="white",fill="white")+
geom_star(data=.%>%filter(clade=="Placodermi",genus!="Dunkleosteus"),starshape=1,size=3.5,fill="black")+
geom_hline(yintercept=0.21,linetype="dashed")+
geom_star(data=.%>% filter(genus=="Dunkleosteus")%>%
mutate(precaudal_length=ifelse(specimen=="CMNH 5768",
-cos(28*(pi/180))*170,
total_length
precaudal_length),precaudal_length=ifelse(specimen=="CMNH 7424",
-cos(22*(pi/180))*80,
total_length
precaudal_length),precaudal_length=ifelse(specimen=="CMNH 7054",
-cos(27*(pi/180))*142,
total_length
precaudal_length),precaudal_length=ifelse(specimen=="CMNH 6090",
-cos(26*(pi/180))*132,
total_length
precaudal_length)),starshape=1,size=3.5,fill="yellow",color="black")+
annotate(geom="text",x=680,y=0.155,hjust=1,label="Dunkleosteus",fontface=3)+
scale_fill_manual(values=c(hue_pal()(5),"gray"))+
scale_x_continuous(trans="log10")+
scale_y_continuous(labels=scales::percent_format(accuracy=1))+
labs(x="Precaudal Length (cm)",y="Percent Head Length",fill="Body Shape",starshape="Clade")+
theme_classic()+
guides(fill=guide_legend(nrow=2,override.aes = list(starshape=15)),
starshape=guide_legend(nrow=2))+
theme(legend.position="bottom",legend.box = "horizontal")
As can be seen here, this still results in Dunkleosteus terrelli plotting as a large outlier to almost all other fishes, particularly fusiform species.
9.3 Treating head length in arthrodires as equivalent to prebranchial length
ggplot(data_mouths%>%
drop_na(shape)%>%
mutate(prebranchial_length=ifelse(clade=="Placodermi",
%>%
head_length,prebranchial_length))filter(!is.na(prebranchial_length))%>%
filter(clade!="Placodermi"|!is.na(total_length))%>%
mutate(percent_prebranchial_length=prebranchial_length/total_length),
aes(y=percent_prebranchial_length,x=total_length))+
geom_star(aes(fill=shape,starshape=clade))+
scale_starshape_manual(values=c(15,13,1,28))+
scale_fill_manual(values=c(hue_pal()(5),"gray"))+
geom_star(data=.%>%filter(clade=="Placodermi",genus!="Dunkleosteus")%>%
mutate(percent_prebranchial_length=head_length/total_length),
starshape=1,size=5.5,color="white",fill="white")+
geom_star(data=.%>%filter(clade=="Placodermi",genus!="Dunkleosteus")%>%
mutate(percent_prebranchial_length=head_length/total_length),
starshape=1,size=3.5,fill="black")+
geom_star(data=mouth_predictions%>%
filter(genus=="Dunkleosteus")%>%
mutate(total_length=fit.UJP.fitted,
percent_prebranchial_length=head_length/total_length),
starshape=1,
size=3,fill="yellow")+
scale_x_continuous(trans='log10')+
scale_y_continuous(labels=scales::percent_format(accuracy=1))+
annotate(geom="text",x=680,y=0.085,hjust=1,label="Dunkleosteus",fontface=3)+
labs(x="Total Length (cm)",y="Percent Prebranchial Length",fill="Body Shape",
starshape="Clade")+
theme_classic()+
guides(fill=guide_legend(nrow=2,override.aes = list(starshape=15)),
starshape=guide_legend(nrow=2))+
theme(legend.position="bottom",legend.box = "horizontal")
Even if treating head length in arthrodires as equivalent to pre-branchial length in other fishes, this still results in Dunkleosteus having a below-average prebranchial length for its size (plotting among elongate, anguilliform, and macruriform taxa), and does not resemble the patterns seen in other arthrodires, which have “prebranchial lengths” that plot much closer to fusiform fishes.
9.4 Highlighting groupers
ggplot(
%>%
data_mouths drop_na(head_length,total_length)%>%
mutate(percent_head_length=head_length/total_length),
aes(total_length,head_length/total_length))+
geom_star(aes(starshape=clade),fill="light gray",color="dark grey")+
geom_star(data=.%>%filter(family %in% c("Serranidae")),
aes(starshape=clade,fill=family))+
scale_starshape_manual(values=c(15,13,1,28,11),guide="none")+
geom_hline(yintercept=0.17,linetype="dashed")+
annotate(geom="text",x=2,y=0.16,label="Eel-Like Taxa")+
scale_x_continuous(trans="log10")+
scale_y_continuous(labels=scales::percent_format(accuracy=1))+
labs(x="Total Length (cm)",y="Percent Head Length",fill="Clade")+
guides(fill=guide_legend(nrow=2,override.aes = list(starshape=15)))+
theme_classic()+
theme(legend.position=c(0.15,0.1))
9.5 Using lengths of Engelman (2023)
This paper was originally intended to come out before Engelman (2023), in order to lay the groundwork for that study. However, due to the vagaries of publication, Engelman (2023) actually ended up coming out in print first. This study is still written treating the work of Engelman (2023) as if it never existed, but because that study is already out it is possible to make a useful cross-study comparison showing how the length estimates in Engelman (2023) result in Dunkleosteus position within the head-trunk proportions of fishes as a postscript.
<- function(x, ...) paste(strwrap(x, ...), collapse = "\n")
wrapper <-ggplot(
(engelman_head_length%>%
data_mouths drop_na(head_length,total_length)%>%
mutate(percent_head_length=head_length/total_length,
elongate=ifelse(shape %in% c("anguilliform","macruriform")|
%in% c("Cheirocentrus","Coryphaena","Tetrapturus",
genus "Polypterus","Alepisaurus","Gonorynchus",
"Rhaphiodon",
"Thyrsitoides","Gempylus","Thyrsites")|
%in% "Belonidae",
family "Elongate Postcranium","Not Elongate"))%>%
arrange(elongate),
aes(total_length,head_length/total_length))+
geom_star(aes(starshape=clade,fill=elongate),data=.%>%filter(genus!="Dunkleosteus"))+
geom_star(data=.%>%filter(elongate=="Elongate Postcranium",genus!="Dunkleosteus"),
aes(starshape=clade,fill=elongate))+
scale_starshape_manual(values=c(15,13,1,28,11))+
geom_star(data=.%>%filter(clade=="Placodermi",genus!="Dunkleosteus"),
starshape=1,size=4,
color="white",fill="black")+
geom_hline(yintercept=0.17,linetype="longdash")+
geom_segment(data=.%>%filter(specimen=="CMNH 5768") %>% mutate(total_length=340.7),
aes(xend=1100,yend=head_length/total_length),color="black")+
geom_segment(data=.%>%filter(specimen=="CMNH 5768"),
aes(xend=1100,yend=head_length/total_length),color="black")+
geom_star(data=. %>% filter(genus=="Dunkleosteus") %>%
mutate(total_length=case_when(specimen=="CMNH 5768"~340.7,
=="CMNH 7424"~188.9,
specimen=="CMNH 6090"~283.3,
specimen=="CMNH 7054"~295.5)) %>%
specimenmutate(percent_head_length=head_length/total_length),
starshape=1,size=5,fill="white",color="white")+
geom_segment(
data=data_mouths %>% filter(genus=="Dunkleosteus") %>% drop_na(UJP) %>%
mutate(new_length=case_when(specimen=="CMNH 5768"~340.7,
=="CMNH 7424"~188.9,
specimen=="CMNH 6090"~283.3,
specimen=="CMNH 7054"~295.5)) %>%
specimenmutate(percent_head_length1=head_length/total_length,
percent_head_length2=head_length/new_length),
aes(y=percent_head_length1,x=total_length,
yend=percent_head_length2,xend=new_length),
linetype="dashed")+
geom_star(data=. %>% filter(genus=="Dunkleosteus"),
starshape=1,size=4,fill="white",color="black")+
geom_star(data=. %>% filter(genus=="Dunkleosteus"),
starshape=1,size=4,alpha=0.5,fill="yellow",color="grey")+
geom_star(data=. %>% filter(genus=="Dunkleosteus") %>%
mutate(total_length=case_when(specimen=="CMNH 5768"~340.7,
=="CMNH 7424"~188.9,
specimen=="CMNH 6090"~283.3,
specimen=="CMNH 7054"~295.5)) %>%
specimenmutate(percent_head_length=head_length/total_length),
starshape=1,size=4,fill="yellow",color="black")+
annotate(geom="text",x=2,y=0.16,size=3,label="Eel-Like Taxa")+
annotate(geom="text",x=1150,y=0.181,hjust=0,label="Engelman (2023)",
size=3)+
annotate(geom="text",x=1150,y=0.09,hjust=0,
label=wrapper("Ferrón et al. (2017)",width = 14),size=3)+
coord_cartesian(xlim=c(1,2900),ylim=c(0.04,0.39))+
theme_classic()+
scale_x_continuous(trans="log10")+
scale_y_continuous(labels=scales::percent_format(accuracy=1))+
labs(x="Total Length (cm)",y="Percent Head Length",fill="Body Shape",starshape="Clade")+
guides(fill=guide_legend(nrow=2,override.aes = list(starshape=15)),
starshape=guide_legend(ncol=2,override.aes = list(fill="light gray")))+
theme(legend.position="bottom",
legend.text=element_text(size=9),
legend.title=element_text(size=10)))
ggsave("Arthrodire Mouths Engelman Head Lengths.png",engelman_head_length,
width=178,height=134,units="mm",device="png")
As can be seen, the new length estimates result in head-trunk proportions for Dunkleosteus within the range of typical fusiform osteichthyans and chondrichthyans as well as agreeing more closely with those of complete arthrodires, albeit lower than expected based on coccosteomorphs. Amazichthys still plots below the threshhold for taxa with elongate trunks, but then again specimens of Amazichthys show a body plan with an elongate trunk. The fact that Dunkleosteus is close to but perfectly aligns with neither coccosteomorphs nor Amazichthys is to be expected given it is in a separate clade from these groups (Dunkleosteoidea) and in several respects its cranial morphology is decidedly generalized (e.g., it lacks the overhanging neurocranium of coccosteomorphs).
However, the new length estimates just barely put Dunkleosteus terrelli within the range of head-body proportions expected for fishes without greatly elongated trunks. In other words, despite the extremely short, chunky body depicted in Engelman (2023), that body shape is almost the longest Dunkleosteus can be without violating a typical fish body plan.
Again, some fishes like Coryphaena have very elongate trunks and a somewhat fusiform shape, but Dunkleosteus’ preserved anatomy does not show any features indicative of a Coryphaena-like body plan. Dunkleosteus lacks the elongate ventral armor of Amazichthys, and almost every body measurement associated with this species produces lengths that agree with the shorter body plan (Engelman, 2023). Thus, a much longer body shape would be completely speculative, and actually have to disagree with many proportions strongly conserved across fishes.
10 Mouth length
<-data_mouths%>%
(mouth_length_plotdrop_na(clade)%>%
mutate(percent_mouth_length=mouth_length/head_length)%>%
mutate(clade=ifelse(genus=="Dunkleosteus","Dunkleosteus",clade),
clade=ifelse(clade=="Placodermi"&genus!="Dunkleosteus","Other Placodermi",clade))%>%
arrange(rev(clade))%>%
ggplot(aes(head_length,percent_mouth_length))+
geom_star(aes(starshape=clade,fill=clade))+
scale_starshape_manual(values=c(15,13,1,1,28),
labels=c("Actinopterygii","Chondrichthyes","*Dunkleosteus*",
"Other Placodermi","Sarcopterygii"),
breaks=c("Actinopterygii","Chondrichthyes","Dunkleosteus",
"Other Placodermi","Sarcopterygii"))+
scale_fill_manual(values=c(hue_pal()(3)[1],hue_pal()(3)[3],
"yellow","black",hue_pal()(3)[2]),
labels=c("Actinopterygii","Chondrichthyes","*Dunkleosteus*",
"Other Placodermi","Sarcopterygii"),
breaks=c("Actinopterygii","Chondrichthyes","Dunkleosteus",
"Other Placodermi","Sarcopterygii"))+
geom_star(data=.%>%filter(clade=="Other Placodermi",genus!="Dunkleosteus"),size=4,
starshape=1,color="white",fill="black",starstroke=0.5)+
geom_star(data=.%>%filter(genus=="Dunkleosteus"),starshape=1,size=3.5,
color="black",fill="yellow")+
scale_x_continuous(trans="log10")+
scale_y_continuous(labels=scales::percent_format(accuracy=1))+
labs(starshape="Clade",fill="Clade",x="Head Length (cm)",
y="Mouth Length (as percent of Head Length)")+
theme_classic()+
theme(legend.position=c(0.15,0.85),
legend.text=element_markdown()))
ggsave("Arthrodire Mouths Figure 9 (Mouth Length).pdf",mouth_length_plot,
width=165,height=125,units="mm",device="pdf")
Based on this, it is apparent that Dunkleosteus has a much larger mouth (relative to head size) than most other arthrodires, even compared to the closely related dunkleosteoid Eastmanosteus calliaspis. The only arthrodires which has mouth proportions similar to Dunkleosteus are the Frasnian Hadrosteus rapax and the coeval Cleveland Shale arthrodires Heintzichthys gouldii and Bungartius perissus. Even these taxa only have mouths similar in size to juvenile D. terrelli, the adults (which have proportionally larger mouths) have mouths much larger than any other arthrodire.
This result highlights two important points: 1. Dunkleosteus has a proportionally large mouth even among arthrodires (which show much larger mouths relative to length than sharks), which means that estimates based on mouth dimensions are even more likely to be overestimates. 2. Dunkleosteus has an extremely large mouth relative to other arthrodires and this is highly likely to have affected its paleobiology and paleoecology (i.e., taking larger prey than other arthrodires).
11 References
Branstetter S, and Stiles R. 1987. Age and growth estimates of the bull shark, Carcharhinus leucas, from the northern Gulf of Mexico. Environmental Biology of Fishes 20:169–181.
Cliff G. 1995. Sharks caught in the protective gill nets off KwaZulu-Natal, South Africa. 8. The Great hammerhead shark Sphyrna mokarran (Rüppell). South African Journal of Marine Science 15:105-114. DOI 10.2989/025776195784156331.
Dennis K, and Miles RS. 1981. A pachyosteomorph arthrodire from Gogo, Western Australia. Zoological Journal of the Linnean Society 73:213-258. DOI 10.1111/j.1096-3642.1981.tb01594.x.
Desmond AJ. 1974. On the coccosteid arthrodire Millerosteus minor. Zoological Journal of the Linnean Society 54:277-298. DOI 10.1111/j.1096-3642.1974.tb00804.x.
Engelman RK. 2023. A Devonian Fish Tale: A New Method of Body Length Estimation Suggests Much Smaller Sizes for Dunkleosteus terrelli (Placodermi: Arthrodira). Diversity 15:318. DOI 10.3390/d15030318.
Ferrón HG, Martinez-Perez C, and Botella H. 2017. Ecomorphological inferences in early vertebrates: reconstructing Dunkleosteus terrelli (Arthrodira, Placodermi) caudal fin from palaeoecological data. PeerJ 5:e4081. DOI 10.7717/peerj.4081.
Francis MP. 2006. Morphometric minefields—towards a measurement standard for chondrichthyan fishes. Environmental Biology of Fishes 77:407-421. DOI 10.1007/s10641-006-9109-1.
Gardiner BG, and Miles RS. 1994. Eubrachythoracid arthrodires from Gogo, Western Australia. Zoological Journal of the Linnean Society 112:443-477. DOI 10.1111/j.1096-3642.1994.tb00331.x.
Garrick JAF. 1967. Revision of sharks of genus Isurus with description of a new speces (Galeoidea, Lamnidae). Proceedings of the United Stated National Museum 118:663–690.
Gilmore RG. 1983. Observations on the Embryos of the Longfin Mako, Isurus paucus, and the Bigeye Thresher, Alopias superciliosus. Copeia 1983:375-382. DOI 10.2307/1444380.
Hyde JE, and Huwig K. 2004. Images from the Jesse Earl Hyde Collection, Case Western Reserve University (CWRU) Department of Geological Sciences. Available at https://caslabs.case.edu/hyde-collection/ (accessed September 1 2022).
Lowry D, de Castro ALF, Mara K, Whitenack LB, Delius B, Burgess GH, and Motta P. 2009. Determining shark size from forensic analysis of bite damage. Marine Biology 156:2483-2492. DOI 10.1007/s00227-009-1273-3.
Miles RS, and Dennis K. 1979. A primitive eubrachythoracid arthrodire from Gogo, Western Australia. Zoological Journal of the Linnean Society 66:31-62. DOI 10.1111/j.1096-3642.1979.tb01900.x.
Miles RS, and Westoll TS. 1968. The Placoderm Fish Coccosteus cuspidatus Miller ex Agassiz from the Middle Old Red Sandstone of Scotland. Part I. Descriptive Morphology. Transactions of the Royal Society of Edinburgh 67:373-476. DOI 10.1017/S0080456800024078.
Miles RS, and White EI. 1971. The Holonematidae (placoderm fishes), a review based on new specimens of Holonema from the Upper Devonian of Western Australia. Philosophical Transactions of the Royal Society of London B, Biological Sciences 263:101-234. DOI 10.1098/rstb.1971.0111.
Piercy AN, Carlson JK, Sulikowski JA, and Burgess GH. 2007. Age and growth of the scalloped hammerhead shark, Sphyrna lewini, in the north-west Atlantic Ocean and Gulf of Mexico. Marine and Freshwater Research 58:34-40.
Pollack AG, Driggers WB, III, Hanisko DS, and Ingram GW, Jr. 2019. Distribution and Length Data for Blacktip Sharks Captured on the NOAA/NMFS/SEFSC/MSLABS Bottom Longline Survey in the Western North Atlantic Ocean. North Charleston: SEDAR. p 16.
Randall JE. 1997. Randall’s tank photos. Collection of 10,000 large-format photos (slides) of dead fishes. Available at www.fishbase.org (see species pages for more details) (accessed June 29 2022).
Trinajstic K. 1999. New anatomical information on Holonema (Placodermi) based on material from the Frasnian Gogo Formation and the Givetian-Frasnian Gneudna Formation, Western Australia. Geodiversitas 21:69-84.
Trinajstic K, Briggs DEG, and Long JA. 2022. The Gogo Formation Lagerstätte: a view of Australia’s first great barrier reef. Journal of the Geological Society 179:jgs2021-2105. DOI 10.1144/jgs2021-105.
Trinajstic K, Sanchez S, Dupret V, Tafforeau P, Long J, Young G, Senden T, Boisvert C, Power N, and Ahlberg PE. 2013. Fossil musculature of the most primitive jawed vertebrates. Science 341:160-164. DOI 10.1126/science.1237275.
Vézina D. 1988. Plourdosteus canadensis (Woodward 1892), un Arthrodire du Frasnien inférieur du Canada: contribution à l’étude morphologique et phylogénétique des Plourdosteidae (Vertebrata, Placodermi) du Dévonien moyen et supérieur. PhD. l’Université de Paris VII.
Vézina D. 1990. Les Plourdosteidae fam. nov. (Placodermi, Arthrodira) et leurs relations phylétiques au sein des Brachythoraci. Canadian Journal of Earth Sciences 27:677-683. DOI 10.1139/e90-065.
Whitney NM, and Crow GL. 2007. Reproductive biology of the tiger shark (Galeocerdo cuvier) in Hawaii. Marine Biology 151:63-70. DOI 10.1007/s00227-006-0476-0.
12 Session Information
::session_info() xfun
## R version 4.2.1 (2022-06-23 ucrt)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## Running under: Windows 10 x64 (build 22621)
##
## Locale:
## LC_COLLATE=English_United States.utf8
## LC_CTYPE=English_United States.utf8
## LC_MONETARY=English_United States.utf8
## LC_NUMERIC=C
## LC_TIME=English_United States.utf8
##
## Package version:
## askpass_1.1 assertthat_0.2.1 backports_1.4.1
## base64enc_0.1.3 bit_4.0.4 bit64_4.0.5
## blob_1.2.3 bookdown_0.30 broom_1.0.1
## bslib_0.4.1 cachem_1.0.6 callr_3.7.3
## cellranger_1.1.0 cli_3.4.1 clipr_0.8.0
## colorspace_2.0-3 commonmark_1.8.1 compiler_4.2.1
## cowplot_1.1.1 cpp11_0.4.3 crayon_1.5.2
## curl_4.3.3 data.table_1.14.4 DBI_1.1.3
## dbplyr_2.2.1 digest_0.6.30 dplyr_1.0.10
## dtplyr_1.2.2 ellipsis_0.3.2 evaluate_0.18
## fansi_1.0.3 farver_2.1.1 fastmap_1.1.0
## forcats_0.5.2 fs_1.5.2 gargle_1.2.1
## generics_0.1.3 ggplot2_3.4.0 ggstar_1.0.4
## ggtext_0.1.2 glue_1.6.2 googledrive_2.0.0
## googlesheets4_1.0.1 graphics_4.2.1 grDevices_4.2.1
## grid_4.2.1 gridExtra_2.3 gridtext_0.1.5
## gtable_0.3.1 haven_2.5.1 highr_0.9
## hms_1.1.2 htmltools_0.5.3 httr_1.4.4
## ids_1.0.1 isoband_0.2.7 jpeg_0.1.9
## jquerylib_0.1.4 jsonlite_1.8.3 kableExtra_1.3.4
## knitr_1.40 labeling_0.4.2 lattice_0.20-45
## lifecycle_1.0.3 lubridate_1.9.0 magick_2.7.3
## magrittr_2.0.3 markdown_1.3 MASS_7.3.58.1
## Matrix_1.5-1 memoise_2.0.1 methods_4.2.1
## mgcv_1.8-40 mime_0.12 modelr_0.1.10
## munsell_0.5.0 nlme_3.1-160 openssl_2.0.4
## pillar_1.8.1 pkgconfig_2.0.3 png_0.1.7
## prettyunits_1.1.1 processx_3.8.0 progress_1.2.2
## ps_1.7.2 purrr_0.3.5 R6_2.5.1
## ragg_1.2.4 rappdirs_0.3.3 RColorBrewer_1.1.3
## Rcpp_1.0.9 readr_2.1.3 readxl_1.4.1
## rematch_1.0.1 rematch2_2.1.2 reprex_2.0.2
## rlang_1.0.6 rmarkdown_2.18 rmdformats_1.0.4.9000
## rstudioapi_0.14 rvest_1.0.3 sass_0.4.2
## scales_1.2.1 selectr_0.4.2 splines_4.2.1
## stats_4.2.1 stringi_1.7.8 stringr_1.4.1
## svglite_2.1.0 sys_3.4.1 systemfonts_1.0.4
## textshaping_0.3.6 tibble_3.1.8 tidyr_1.2.1
## tidyselect_1.2.0 tidyverse_1.3.2 timechange_0.1.1
## tinytex_0.42 tools_4.2.1 tzdb_0.3.0
## utf8_1.2.2 utils_4.2.1 uuid_1.1.0
## vctrs_0.5.0 viridisLite_0.4.1 vroom_1.6.0
## webshot_0.5.4 withr_2.5.0 xfun_0.34
## xml2_1.3.3 yaml_2.3.6