Data analysis for:
Why are telomeres the length that they are? Insight from a phylogenetic comparative analysisWorkflow of the analyses produced by Dylan Padilla, School of Life Sciences, Arizona State University, Tempe, AZ 85287, USA.
Library
library(AICcmodavg)
library(ape)
library(caper)
library(car)
library(coda)
library(extrafont)
library(geiger)
library(graph)
library(kableExtra)
library(MuMIn)
library(nlme)
library(pbapply)
library(phylopath)
library(phytools)
library(plotrix)
library(rphylopic)
library(scales)
library(sensiPhy)
library(shape)
library(xtable)
R.version
> _
> platform aarch64-apple-darwin20
> arch aarch64
> os darwin20
> system aarch64, darwin20
> status
> major 4
> minor 3.3
> year 2024
> month 02
> day 29
> svn rev 86002
> language R
> version.string R version 4.3.3 (2024-02-29)
> nickname Angel Food Cake
sessionInfo()
> R version 4.3.3 (2024-02-29)
> Platform: aarch64-apple-darwin20 (64-bit)
> Running under: macOS 15.1
>
> Matrix products: default
> BLAS: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRblas.0.dylib
> LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.11.0
>
> locale:
> [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
>
> time zone: America/Phoenix
> tzcode source: internal
>
> attached base packages:
> [1] stats graphics grDevices utils datasets methods base
>
> other attached packages:
> [1] rmarkdown_2.26 xtable_1.8-4 shape_1.4.6.1 sensiPhy_0.8.5 ggplot2_3.5.1
> [6] phylolm_2.6.2 scales_1.3.0 rphylopic_1.4.0 plotrix_3.8-4 phylopath_1.2.1
> [11] pbapply_1.7-2 nlme_3.1-164 MuMIn_1.47.5 kableExtra_1.4.0 graph_1.80.0
> [16] BiocGenerics_0.48.1 geiger_2.0.11 phytools_2.1-1 maps_3.4.2 extrafont_0.19
> [21] coda_0.19-4.1 car_3.1-2 carData_3.0-5 caper_1.0.3 mvtnorm_1.2-4
> [26] MASS_7.3-60.0.1 ape_5.8 AICcmodavg_2.3-3
>
> loaded via a namespace (and not attached):
> [1] mnormt_2.1.1 gridExtra_2.3 phangorn_2.11.1 rlang_1.1.3
> [5] magrittr_2.0.3 compiler_4.3.3 png_0.1-8 systemfonts_1.0.6
> [9] vctrs_0.6.5 combinat_0.0-8 quadprog_1.5-8 stringr_1.5.1
> [13] pkgconfig_2.0.3 fastmap_1.1.1 labeling_0.4.3 ggraph_2.2.1
> [17] utf8_1.2.4 subplex_1.8 deSolve_1.40 purrr_1.0.2
> [21] xfun_0.43 cachem_1.0.8 clusterGeneration_1.3.8 jsonlite_1.8.8
> [25] tweenr_2.0.3 jpeg_0.1-10 VGAM_1.1-10 parallel_4.3.3
> [29] R6_2.5.1 bslib_0.7.0 stringi_1.8.3 parallelly_1.37.1
> [33] extrafontdb_1.0 jquerylib_0.1.4 numDeriv_2016.8-1.1 Rcpp_1.0.12
> [37] iterators_1.0.14 knitr_1.45 future.apply_1.11.2 optimParallel_1.0-2
> [41] ggm_2.5.1 base64enc_0.1-3 Matrix_1.6-5 splines_4.3.3
> [45] igraph_2.0.3 tidyselect_1.2.1 yaml_2.3.8 viridis_0.6.5
> [49] rstudioapi_0.16.0 abind_1.4-5 doParallel_1.0.17 codetools_0.2-19
> [53] curl_5.2.1 listenv_0.9.1 lattice_0.22-5 tibble_3.2.1
> [57] withr_3.0.0 evaluate_0.23 future_1.33.2 survival_3.5-8
> [61] polyclip_1.10-6 xml2_1.3.6 BiocManager_1.30.22 pillar_1.9.0
> [65] foreach_1.5.2 stats4_4.3.3 generics_0.1.3 grImport2_0.3-1
> [69] munsell_0.5.1 globals_0.16.3 glue_1.7.0 unmarked_1.4.1
> [73] scatterplot3d_0.3-44 tools_4.3.3 graphlayouts_1.1.1 XML_3.99-0.16.1
> [77] tidygraph_1.3.1 fastmatch_1.1-4 grid_4.3.3 tidyr_1.3.1
> [81] Rttf2pt1_1.3.12 colorspace_2.1-0 ggforce_0.4.2 cli_3.6.2
> [85] rsvg_2.6.0 fansi_1.0.6 expm_0.999-9 viridisLite_0.4.2
> [89] svglite_2.1.3 dplyr_1.1.4 gtable_0.3.5 sass_0.4.9
> [93] digest_0.6.35 ggrepel_0.9.5 farver_2.1.1 memoise_2.0.1
> [97] htmltools_0.5.8.1 lifecycle_1.0.4 httr_1.4.7
set.seed(80)
## Dataset
data <- read.csv('data.csv')
str(data)
> 'data.frame': 122 obs. of 26 variables:
> $ Common.name : chr "Barn swallow " "Northern goshawks " "Orange-winged Amazon parrot " "Red tail hawk " ...
> $ Scientific_name : chr "Hirundo_rustica" "Accipiter_gentilis" "Amazona_amazonica" "Buteo_jamaicensis" ...
> $ Domain : chr "Eukaryota" "Eukaryota" "Eukaryota" "Eukaryota" ...
> $ Kingdom : chr "Metazoa" "Metazoa" "Metazoa" "Metazoa" ...
> $ Phylum : chr "Chordata" "Chordata" "Chordata" "Chordata" ...
> $ Class : chr "Aves" "Aves" "Aves" "Aves" ...
> $ Order : chr "Passeriformes" "Accipitriformes" "Psittaciformes" "Accipitriformes" ...
> $ Family : chr "Hirundinidae" "Accipitridae" "Psittacidae" "Accipitridae" ...
> $ Genus : chr "Hirundo" "Accipiter" "Amazona" "Buteo" ...
> $ Species : chr "rustica" "gentilis" "amazonica" "jamaicensis" ...
> $ Endo_ectotherm : chr "endo" "endo" "endo" "endo" ...
> $ Adult_mass_grams : num 18.3 1044 370 1362 980.6 ...
> $ Lifespan_years : num 16 22 30 30.7 24.9 13.4 6.4 15 50 17 ...
> $ Average_Telomere_Length_kb: num 8.7 1.3 11.8 13.3 42.4 3.2 23.4 3.44 9.9 30.2 ...
> $ Telomerase_activity : int NA NA NA NA NA NA NA NA NA NA ...
> $ Tissue.type.for.TA : chr NA NA NA NA ...
> $ Source.for.TA : chr NA NA NA NA ...
> $ Tissue.type.for.TL : chr "Blood" "Blood" "Blood" "Blood" ...
> $ Tissue_coded : chr "A" "A" "A" "A" ...
> $ Methodology.for.TL : chr "TRF (combination)" "TRF (denatured)" "TRF (denatured)" "TRF (denatured)" ...
> $ method : chr "A" "B" "B" "B" ...
> $ Source.for.TL : chr "Caprioli 2012; Foote et al. 2013; Tricola et al. 2018; Criscuolo et al. 2021" "Delany et al. 2000; Criscuolo et al. 2021" "Delany et al. 2000; Criscuolo et al. 2021" "Delany et al. 2000" ...
> $ Source.for.Lifespan : chr "AnAge" "AnAge" "AnAge" "AnAge" ...
> $ Source.for.Mass : chr "AnAge" "AnAge" "AnAge" "AnAge" ...
> $ Captivity : int 0 0 0 0 0 0 0 0 0 0 ...
> $ Notes : chr "" "" "" "" ...
head(data)
> Common.name Scientific_name Domain Kingdom Phylum Class Order
> 1 Barn swallow Hirundo_rustica Eukaryota Metazoa Chordata Aves Passeriformes
> 2 Northern goshawks Accipiter_gentilis Eukaryota Metazoa Chordata Aves Accipitriformes
> 3 Orange-winged Amazon parrot Amazona_amazonica Eukaryota Metazoa Chordata Aves Psittaciformes
> 4 Red tail hawk Buteo_jamaicensis Eukaryota Metazoa Chordata Aves Accipitriformes
> 5 Swainson's hawk Buteo_swainsoni Eukaryota Metazoa Chordata Aves Accipitriformes
> 6 Golden pheasant Chrysolophus_pictus Eukaryota Metazoa Chordata Aves Galliformes
> Family Genus Species Endo_ectotherm Adult_mass_grams Lifespan_years
> 1 Hirundinidae Hirundo rustica endo 18.30 16.0
> 2 Accipitridae Accipiter gentilis endo 1044.00 22.0
> 3 Psittacidae Amazona amazonica endo 370.00 30.0
> 4 Accipitridae Buteo jamaicensis endo 1362.00 30.7
> 5 Accipitridae Buteo swainsoni endo 980.64 24.9
> 6 Phasianidae Chrysolophus pictus endo 625.00 13.4
> Average_Telomere_Length_kb Telomerase_activity Tissue.type.for.TA Source.for.TA Tissue.type.for.TL
> 1 8.7 NA <NA> <NA> Blood
> 2 1.3 NA <NA> <NA> Blood
> 3 11.8 NA <NA> <NA> Blood
> 4 13.3 NA <NA> <NA> Blood
> 5 42.4 NA <NA> <NA> Blood
> 6 3.2 NA <NA> <NA> Blood
> Tissue_coded Methodology.for.TL method
> 1 A TRF (combination) A
> 2 A TRF (denatured) B
> 3 A TRF (denatured) B
> 4 A TRF (denatured) B
> 5 A TRF (denatured) B
> 6 A TRF (denatured) B
> Source.for.TL Source.for.Lifespan
> 1 Caprioli 2012; Foote et al. 2013; Tricola et al. 2018; Criscuolo et al. 2021 AnAge
> 2 Delany et al. 2000; Criscuolo et al. 2021 AnAge
> 3 Delany et al. 2000; Criscuolo et al. 2021 AnAge
> 4 Delany et al. 2000 AnAge
> 5 Delany et al. 2000; Criscuolo et al. 2021 AnAge
> 6 Delaney et al. 2000; Criscuolo et al. 2021 AnAge
> Source.for.Mass Captivity Notes
> 1 AnAge 0
> 2 AnAge 0
> 3 AnAge 0
> 4 AnAge 0
> 5 AnAge 0
> 6 AnAge 0
unique(data$Family)
> [1] "Hirundinidae" "Accipitridae" "Psittacidae" "Phasianidae" "Odontophoridae"
> [6] "Moronidae" "Diomedeidae" "Falconidae" "Procellaridae" "Laridae"
> [11] "Strigopidae" "Apodidae" "Carangidae" "Cyprinidae" "Lutjanidae"
> [16] "Mullidae" "Sparidae" "Percichthyidae" "Nothobranchiidae" "Gadidae"
> [21] "Platycephalidae" "Salmonidae" "Neoceratodontidae" "Urolophidae" "Callorhinchidae"
> [26] "Muridae" "Chinchillidae" "Cricetidae" "Myocastoridae" "Sciuridae"
> [31] "Otariidae" "Castoridae" "Atelidae" "Hyaenidae" "Aplodontiidae"
> [36] "Balaenidae" "Hominidae" "Pteropodidae" "Cebidae" "Rhinocerotidae"
> [41] "Giraffidae" "Caviidae" "Equidae" "Myrmecophagidae" "Tapiridae"
> [46] "Ursidae" "Chlamyphoridae" "Eschrichtiidae" "Elephantidae" "Cervidae"
> [51] "Procaviidae" "Tupaiidae" "Heterocephalidae" "Cercopithecidae" "Choloepodidae"
> [56] "Delphinidae" "Lemuridae" "Ochotonidae" "Ailuridae" "Molossidae"
> [61] "Vespertilionidae" "Didelphidae" "Macroscelididae" "Erinaceidae" "Leporidae"
> [66] "Felidae" "Tenrecidae" "Alligatoridae" "Lacertidae" "Pythonidae"
> [71] "Emydidae" "Estrildidae" "Corvidae" "Anatidae" "Scolopacidae"
> [76] "Alcidae" "Fregatidae" "Haematopotidae" "Hydrobatidae" "Paridae"
> [81] "Emberizidae" "Spheniscidae" "Sternidae" "Pelecani" "Turdidae"
> [86] "Vireonidae" "Poeciliidae" "Testudinoidea"
dat <- data
names(dat)
> [1] "Common.name" "Scientific_name" "Domain"
> [4] "Kingdom" "Phylum" "Class"
> [7] "Order" "Family" "Genus"
> [10] "Species" "Endo_ectotherm" "Adult_mass_grams"
> [13] "Lifespan_years" "Average_Telomere_Length_kb" "Telomerase_activity"
> [16] "Tissue.type.for.TA" "Source.for.TA" "Tissue.type.for.TL"
> [19] "Tissue_coded" "Methodology.for.TL" "method"
> [22] "Source.for.TL" "Source.for.Lifespan" "Source.for.Mass"
> [25] "Captivity" "Notes"
unique(is.na(dat$log_mass))
> logical(0)
## Trees
##write.table(data$Scientific_name, 'spp.tree.08-03-24.txt', row.names = FALSE, col.names = FALSE)
full_data_tree <- read.tree("spp.tree.08-03-24.nwk")
is.ultrametric(full_data_tree)
> [1] FALSE
full_data_tree <- force.ultrametric(full_data_tree)
> ***************************************************************
> * Note: *
> * force.ultrametric does not include a formal method to *
> * ultrametricize a tree & should only be used to coerce *
> * a phylogeny that fails is.ultrametric due to rounding -- *
> * not as a substitute for formal rate-smoothing methods. *
> ***************************************************************
is.ultrametric(full_data_tree)
> [1] TRUE
full_data_tree
>
> Phylogenetic tree with 138 tips and 137 internal nodes.
>
> Tip labels:
> Urolophus_paucimaculatus, Callorhinchus_milii, Oncorhynchus_mykiss, Lutjanus_argentimaculatus, Acanthopagrus_schlegelii, Dicentrarchus_labrax, ...
> Node labels:
> , '14', '12', '48', '57', '49', ...
>
> Rooted; includes branch lengths.
rownames(dat) <- dat$Scientific_name
## Full_tree
check <- name.check(full_data_tree, dat)
rm_phy <- check$tree_not_data
rm_dat <- check$data_not_tree
pruned_data_tree <- drop.tip(full_data_tree, rm_phy)
pruned_dat <- subset(dat, subset = dat$Scientific_name %in% pruned_data_tree$tip, select = names(dat))
str(pruned_dat)
> 'data.frame': 122 obs. of 26 variables:
> $ Common.name : chr "Barn swallow " "Northern goshawks " "Orange-winged Amazon parrot " "Red tail hawk " ...
> $ Scientific_name : chr "Hirundo_rustica" "Accipiter_gentilis" "Amazona_amazonica" "Buteo_jamaicensis" ...
> $ Domain : chr "Eukaryota" "Eukaryota" "Eukaryota" "Eukaryota" ...
> $ Kingdom : chr "Metazoa" "Metazoa" "Metazoa" "Metazoa" ...
> $ Phylum : chr "Chordata" "Chordata" "Chordata" "Chordata" ...
> $ Class : chr "Aves" "Aves" "Aves" "Aves" ...
> $ Order : chr "Passeriformes" "Accipitriformes" "Psittaciformes" "Accipitriformes" ...
> $ Family : chr "Hirundinidae" "Accipitridae" "Psittacidae" "Accipitridae" ...
> $ Genus : chr "Hirundo" "Accipiter" "Amazona" "Buteo" ...
> $ Species : chr "rustica" "gentilis" "amazonica" "jamaicensis" ...
> $ Endo_ectotherm : chr "endo" "endo" "endo" "endo" ...
> $ Adult_mass_grams : num 18.3 1044 370 1362 980.6 ...
> $ Lifespan_years : num 16 22 30 30.7 24.9 13.4 6.4 15 50 17 ...
> $ Average_Telomere_Length_kb: num 8.7 1.3 11.8 13.3 42.4 3.2 23.4 3.44 9.9 30.2 ...
> $ Telomerase_activity : int NA NA NA NA NA NA NA NA NA NA ...
> $ Tissue.type.for.TA : chr NA NA NA NA ...
> $ Source.for.TA : chr NA NA NA NA ...
> $ Tissue.type.for.TL : chr "Blood" "Blood" "Blood" "Blood" ...
> $ Tissue_coded : chr "A" "A" "A" "A" ...
> $ Methodology.for.TL : chr "TRF (combination)" "TRF (denatured)" "TRF (denatured)" "TRF (denatured)" ...
> $ method : chr "A" "B" "B" "B" ...
> $ Source.for.TL : chr "Caprioli 2012; Foote et al. 2013; Tricola et al. 2018; Criscuolo et al. 2021" "Delany et al. 2000; Criscuolo et al. 2021" "Delany et al. 2000; Criscuolo et al. 2021" "Delany et al. 2000" ...
> $ Source.for.Lifespan : chr "AnAge" "AnAge" "AnAge" "AnAge" ...
> $ Source.for.Mass : chr "AnAge" "AnAge" "AnAge" "AnAge" ...
> $ Captivity : int 0 0 0 0 0 0 0 0 0 0 ...
> $ Notes : chr "" "" "" "" ...
head(pruned_dat)
> Common.name Scientific_name Domain Kingdom Phylum Class
> Hirundo_rustica Barn swallow Hirundo_rustica Eukaryota Metazoa Chordata Aves
> Accipiter_gentilis Northern goshawks Accipiter_gentilis Eukaryota Metazoa Chordata Aves
> Amazona_amazonica Orange-winged Amazon parrot Amazona_amazonica Eukaryota Metazoa Chordata Aves
> Buteo_jamaicensis Red tail hawk Buteo_jamaicensis Eukaryota Metazoa Chordata Aves
> Buteo_swainsoni Swainson's hawk Buteo_swainsoni Eukaryota Metazoa Chordata Aves
> Chrysolophus_pictus Golden pheasant Chrysolophus_pictus Eukaryota Metazoa Chordata Aves
> Order Family Genus Species Endo_ectotherm
> Hirundo_rustica Passeriformes Hirundinidae Hirundo rustica endo
> Accipiter_gentilis Accipitriformes Accipitridae Accipiter gentilis endo
> Amazona_amazonica Psittaciformes Psittacidae Amazona amazonica endo
> Buteo_jamaicensis Accipitriformes Accipitridae Buteo jamaicensis endo
> Buteo_swainsoni Accipitriformes Accipitridae Buteo swainsoni endo
> Chrysolophus_pictus Galliformes Phasianidae Chrysolophus pictus endo
> Adult_mass_grams Lifespan_years Average_Telomere_Length_kb Telomerase_activity
> Hirundo_rustica 18.30 16.0 8.7 NA
> Accipiter_gentilis 1044.00 22.0 1.3 NA
> Amazona_amazonica 370.00 30.0 11.8 NA
> Buteo_jamaicensis 1362.00 30.7 13.3 NA
> Buteo_swainsoni 980.64 24.9 42.4 NA
> Chrysolophus_pictus 625.00 13.4 3.2 NA
> Tissue.type.for.TA Source.for.TA Tissue.type.for.TL Tissue_coded Methodology.for.TL
> Hirundo_rustica <NA> <NA> Blood A TRF (combination)
> Accipiter_gentilis <NA> <NA> Blood A TRF (denatured)
> Amazona_amazonica <NA> <NA> Blood A TRF (denatured)
> Buteo_jamaicensis <NA> <NA> Blood A TRF (denatured)
> Buteo_swainsoni <NA> <NA> Blood A TRF (denatured)
> Chrysolophus_pictus <NA> <NA> Blood A TRF (denatured)
> method Source.for.TL
> Hirundo_rustica A Caprioli 2012; Foote et al. 2013; Tricola et al. 2018; Criscuolo et al. 2021
> Accipiter_gentilis B Delany et al. 2000; Criscuolo et al. 2021
> Amazona_amazonica B Delany et al. 2000; Criscuolo et al. 2021
> Buteo_jamaicensis B Delany et al. 2000
> Buteo_swainsoni B Delany et al. 2000; Criscuolo et al. 2021
> Chrysolophus_pictus B Delaney et al. 2000; Criscuolo et al. 2021
> Source.for.Lifespan Source.for.Mass Captivity Notes
> Hirundo_rustica AnAge AnAge 0
> Accipiter_gentilis AnAge AnAge 0
> Amazona_amazonica AnAge AnAge 0
> Buteo_jamaicensis AnAge AnAge 0
> Buteo_swainsoni AnAge AnAge 0
> Chrysolophus_pictus AnAge AnAge 0
pruned_data_tree
>
> Phylogenetic tree with 122 tips and 121 internal nodes.
>
> Tip labels:
> Urolophus_paucimaculatus, Callorhinchus_milii, Oncorhynchus_mykiss, Lutjanus_argentimaculatus, Acanthopagrus_schlegelii, Dicentrarchus_labrax, ...
> Node labels:
> , '14', '12', '48', '57', '49', ...
>
> Rooted; includes branch lengths.
name.check(pruned_data_tree, pruned_dat)
> [1] "OK"
## Checking the distribution of lifespan
plot(NA, xlim = c(0, 200), ylim = c(0, 60), type = 'n', las = 1, xlab = '', ylab = '', axes = FALSE)
grid()
par(new = TRUE)
hist(pruned_dat$Lifespan_years, main = "Raw variable", las = 1, xlab = 'Lifespan (years)')
box()
plot(NA, xlim = c(0, 200), ylim = c(0, 60), type = 'n', las = 1, xlab = '', ylab = '', axes = FALSE)
grid()
par(new = TRUE)
hist(log1p(pruned_dat$Lifespan_years), main = "Log-transformed", xlab = 'Log lifespan (years)', las = 1)
box()
## Log-transforming for a better fit
pruned_dat$log.lifespan <- log1p(pruned_dat$Lifespan_years)
pruned_dat$log.mass <- log1p(pruned_dat$Adult_mass_grams)
## Defining models
str(pruned_dat)
> 'data.frame': 122 obs. of 28 variables:
> $ Common.name : chr "Barn swallow " "Northern goshawks " "Orange-winged Amazon parrot " "Red tail hawk " ...
> $ Scientific_name : chr "Hirundo_rustica" "Accipiter_gentilis" "Amazona_amazonica" "Buteo_jamaicensis" ...
> $ Domain : chr "Eukaryota" "Eukaryota" "Eukaryota" "Eukaryota" ...
> $ Kingdom : chr "Metazoa" "Metazoa" "Metazoa" "Metazoa" ...
> $ Phylum : chr "Chordata" "Chordata" "Chordata" "Chordata" ...
> $ Class : chr "Aves" "Aves" "Aves" "Aves" ...
> $ Order : chr "Passeriformes" "Accipitriformes" "Psittaciformes" "Accipitriformes" ...
> $ Family : chr "Hirundinidae" "Accipitridae" "Psittacidae" "Accipitridae" ...
> $ Genus : chr "Hirundo" "Accipiter" "Amazona" "Buteo" ...
> $ Species : chr "rustica" "gentilis" "amazonica" "jamaicensis" ...
> $ Endo_ectotherm : chr "endo" "endo" "endo" "endo" ...
> $ Adult_mass_grams : num 18.3 1044 370 1362 980.6 ...
> $ Lifespan_years : num 16 22 30 30.7 24.9 13.4 6.4 15 50 17 ...
> $ Average_Telomere_Length_kb: num 8.7 1.3 11.8 13.3 42.4 3.2 23.4 3.44 9.9 30.2 ...
> $ Telomerase_activity : int NA NA NA NA NA NA NA NA NA NA ...
> $ Tissue.type.for.TA : chr NA NA NA NA ...
> $ Source.for.TA : chr NA NA NA NA ...
> $ Tissue.type.for.TL : chr "Blood" "Blood" "Blood" "Blood" ...
> $ Tissue_coded : chr "A" "A" "A" "A" ...
> $ Methodology.for.TL : chr "TRF (combination)" "TRF (denatured)" "TRF (denatured)" "TRF (denatured)" ...
> $ method : chr "A" "B" "B" "B" ...
> $ Source.for.TL : chr "Caprioli 2012; Foote et al. 2013; Tricola et al. 2018; Criscuolo et al. 2021" "Delany et al. 2000; Criscuolo et al. 2021" "Delany et al. 2000; Criscuolo et al. 2021" "Delany et al. 2000" ...
> $ Source.for.Lifespan : chr "AnAge" "AnAge" "AnAge" "AnAge" ...
> $ Source.for.Mass : chr "AnAge" "AnAge" "AnAge" "AnAge" ...
> $ Captivity : int 0 0 0 0 0 0 0 0 0 0 ...
> $ Notes : chr "" "" "" "" ...
> $ log.lifespan : num 2.83 3.14 3.43 3.46 3.25 ...
> $ log.mass : num 2.96 6.95 5.92 7.22 6.89 ...
path.mod <- pruned_dat
names(path.mod)
> [1] "Common.name" "Scientific_name" "Domain"
> [4] "Kingdom" "Phylum" "Class"
> [7] "Order" "Family" "Genus"
> [10] "Species" "Endo_ectotherm" "Adult_mass_grams"
> [13] "Lifespan_years" "Average_Telomere_Length_kb" "Telomerase_activity"
> [16] "Tissue.type.for.TA" "Source.for.TA" "Tissue.type.for.TL"
> [19] "Tissue_coded" "Methodology.for.TL" "method"
> [22] "Source.for.TL" "Source.for.Lifespan" "Source.for.Mass"
> [25] "Captivity" "Notes" "log.lifespan"
> [28] "log.mass"
path.mod$Average_Telomere_Length_kb <- log(path.mod$Average_Telomere_Length_kb)
names(path.mod)[c(14, 11, 28, 27)] <- c('TL', 'M', 'BM', 'LS')
models <- define_model_set(
"null" = c(TL ~ TL, M ~ LS, M ~ BM, LS ~ BM),
"(a)" = c(TL ~ LS, M ~ LS, M ~ BM, BM ~ LS),
"(b)" = c(TL ~ BM, M ~ LS, M ~ BM, BM ~ LS),
"(c)" = c(TL ~ M, M ~ LS, M ~ BM, BM ~ LS),
"(d)" = c(TL ~ BM + LS + M),
"(e)" = c(TL ~ LS),
"(f)" = c(TL ~ BM),
"(g)" = c(TL ~ M))
#png("figureS1-revised.png", width = 7, height = 7, units = "in", res = 360)
#pdf("figureS1-revised.pdf")
plot_model_set(models, nrow = 4) + ggplot2::scale_y_continuous(expand = c(0.1, 0)) + theme(plot.margin=unit(c(0.5, 3, 0.5, 3), "cm"))
#dev.off()
mo <- phylo_path(models, path.mod, pruned_data_tree)
s <- summary(mo)
s
> model k q C p CICc delta_CICc l w
> (b) (b) 2 8 4.90 2.98e-01 22.2 0.00 1.00e+00 6.42e-01
> (a) (a) 2 8 6.14 1.89e-01 23.4 1.25 5.37e-01 3.44e-01
> null null 3 7 16.13 1.31e-02 31.1 8.94 1.14e-02 7.35e-03
> (c) (c) 2 8 14.08 7.06e-03 31.3 9.18 1.02e-02 6.53e-03
> (d) (d) 3 7 48.20 1.08e-08 63.2 41.01 1.25e-09 7.99e-10
> (f) (f) 5 5 52.90 7.77e-08 63.4 41.25 1.11e-09 7.09e-10
> (e) (e) 5 5 54.48 3.95e-08 65.0 42.82 5.02e-10 3.22e-10
> (g) (g) 5 5 70.06 4.31e-11 80.6 58.41 2.08e-13 1.33e-13
theme_set(theme_bw())
## Conditional independence tested
mo$d_sep$'(b)'
> # A tibble: 2 × 4
> d_sep p phylo_par model
> <chr> <dbl> <dbl> <list>
> 1 TL ~ BM + LS 0.302 0.538 <phylolm>
> 2 TL ~ LS + BM + M 0.286 0.529 <phylolm>
bar.pl <- tapply(s$w, list(s$model), print)
> [1] 0.344336
> [1] 0.6417914
> [1] 0.006525674
> [1] 7.99095e-10
> [1] 3.224665e-10
> [1] 7.094764e-10
> [1] 1.332557e-13
> [1] 0.007346913
p.val <- s[names(bar.pl), ]
knitr::kable(s, digits = 3, caption = 'Competing models of the evolution of telomere length across vertebrates', align = 'l', row.names = FALSE, table.attr = "style='width:30%;'")
model | k | q | C | p | CICc | delta_CICc | l | w |
---|---|---|---|---|---|---|---|---|
(b) | 2 | 8 | 4.898 | 0.298 | 22.172 | 0.000 | 1.000 | 0.642 |
(a) | 2 | 8 | 6.143 | 0.189 | 23.418 | 1.245 | 0.537 | 0.344 |
null | 3 | 7 | 16.130 | 0.013 | 31.112 | 8.940 | 0.011 | 0.007 |
(c) | 2 | 8 | 14.075 | 0.007 | 31.349 | 9.177 | 0.010 | 0.007 |
(d) | 3 | 7 | 48.198 | 0.000 | 63.180 | 41.008 | 0.000 | 0.000 |
(f) | 5 | 5 | 52.901 | 0.000 | 63.418 | 41.246 | 0.000 | 0.000 |
(e) | 5 | 5 | 54.478 | 0.000 | 64.995 | 42.823 | 0.000 | 0.000 |
(g) | 5 | 5 | 70.061 | 0.000 | 80.578 | 58.406 | 0.000 | 0.000 |
bt <- best(mo)
plot(bt, algorithm = 'mds') + theme(legend.position= 'none')
A visualization of the best supported causal model, and the standardized path coefficients.
##png("figureS1.png", width = 7, height = 7, units = "in", res = 360)
barplot(NA, beside = TRUE, space = FALSE, horiz = TRUE, xlim = c(0, 1), axes = FALSE)
grid()
par(new = TRUE)
## Adjust the col argument to make the "b" bar red
barplot(bar.pl, beside = TRUE, space = FALSE, horiz = TRUE, xlim = c(0, 1), yaxt = 'n', ylab = 'Candidate models', xlab='Weight of evidence (w)', col = c('gray', alpha('red', 0.3), rep('gray', 6)))
axis(2, at = (0:7)+0.5, labels = names(bar.pl), las = 1)
box()
text(x = round(bar.pl, 3)+0.05, y = (0:7)+0.5, labels = round(p.val$p, 3))
legend('topright', legend = 'within 2 CICc', fill = alpha('red', 0.3), bty = 'n')
Relative importance of the causal models describing the evolution of telomere length across vertebrates. Bar labels are p-values; significance indicates rejection.
##dev.off()
knitr::kable(mo$d_sep$'(b)'[1:2, 1:3], digits = 3, caption = 'Conditional independence statements tested', align = 'l', row.names = FALSE, table.attr = "style='width:30%;'")
d_sep | p | phylo_par |
---|---|---|
TL ~ BM + LS | 0.302 | 0.538 |
TL ~ LS + BM + M | 0.286 | 0.529 |
Fitting models of evolution based on the conditional independence statements tested in the most likely path model
pagel.model0 <- gls(log(Average_Telomere_Length_kb) ~ log.mass + log.lifespan + Endo_ectotherm, correlation = corPagel(0, phy = pruned_data_tree, form = ~Scientific_name), data = pruned_dat, method = "ML")
summary(pagel.model0)
> Generalized least squares fit by maximum likelihood
> Model: log(Average_Telomere_Length_kb) ~ log.mass + log.lifespan + Endo_ectotherm
> Data: pruned_dat
> AIC BIC logLik
> 239.4886 256.3128 -113.7443
>
> Correlation Structure: corPagel
> Formula: ~Scientific_name
> Parameter estimate(s):
> lambda
> 0.5294452
>
> Coefficients:
> Value Std.Error t-value p-value
> (Intercept) 3.524075 0.3908061 9.017450 0.0000
> log.mass -0.036372 0.0265466 -1.370136 0.1732
> log.lifespan -0.130401 0.1185554 -1.099913 0.2736
> Endo_ectothermendo -0.396064 0.3697523 -1.071160 0.2863
>
> Correlation:
> (Intr) lg.mss lg.lfs
> log.mass 0.125
> log.lifespan -0.557 -0.698
> Endo_ectothermendo -0.276 -0.033 0.062
>
> Standardized residuals:
> Min Q1 Med Q3 Max
> -2.8434026 -0.3795892 0.2053350 0.7166696 2.1165328
>
> Residual standard error: 0.7751007
> Degrees of freedom: 122 total; 118 residual
pagel.model1 <- gls(log(Average_Telomere_Length_kb) ~ Endo_ectotherm * log.lifespan + log.mass, correlation = corPagel(0, phy = pruned_data_tree, form = ~Scientific_name), data = pruned_dat, method = "ML")
summary(pagel.model1)
> Generalized least squares fit by maximum likelihood
> Model: log(Average_Telomere_Length_kb) ~ Endo_ectotherm * log.lifespan + log.mass
> Data: pruned_dat
> AIC BIC logLik
> 236.9611 256.5893 -111.4806
>
> Correlation Structure: corPagel
> Formula: ~Scientific_name
> Parameter estimate(s):
> lambda
> 0.3972721
>
> Coefficients:
> Value Std.Error t-value p-value
> (Intercept) 2.5930652 0.5014725 5.170902 0.0000
> Endo_ectothermendo 0.9749552 0.6485376 1.503313 0.1355
> log.lifespan 0.1503982 0.1632280 0.921400 0.3587
> log.mass -0.0325013 0.0257028 -1.264504 0.2086
> Endo_ectothermendo:log.lifespan -0.4017335 0.1745440 -2.301617 0.0231
>
> Correlation:
> (Intr) End_ct lg.lfs lg.mss
> Endo_ectothermendo -0.728
> log.lifespan -0.802 0.646
> log.mass 0.070 0.024 -0.461
> Endo_ectothermendo:log.lifespan 0.717 -0.879 -0.717 -0.041
>
> Standardized residuals:
> Min Q1 Med Q3 Max
> -3.2633469 -0.4613341 0.1622935 0.7012716 2.2145824
>
> Residual standard error: 0.7022405
> Degrees of freedom: 122 total; 117 residual
pagel.model2 <- gls(log(Average_Telomere_Length_kb) ~ Endo_ectotherm * log.mass + log.lifespan, correlation = corPagel(0, phy = pruned_data_tree, form = ~Scientific_name), data = pruned_dat, method = "ML")
summary(pagel.model2)
> Generalized least squares fit by maximum likelihood
> Model: log(Average_Telomere_Length_kb) ~ Endo_ectotherm * log.mass + log.lifespan
> Data: pruned_dat
> AIC BIC logLik
> 235.6954 255.3236 -110.8477
>
> Correlation Structure: corPagel
> Formula: ~Scientific_name
> Parameter estimate(s):
> lambda
> 0.4719298
>
> Coefficients:
> Value Std.Error t-value p-value
> (Intercept) 2.9464763 0.4285141 6.876032 0.0000
> Endo_ectothermendo 0.3990165 0.4646744 0.858701 0.3923
> log.mass 0.0491984 0.0435613 1.129404 0.2610
> log.lifespan -0.1561544 0.1155990 -1.350828 0.1794
> Endo_ectothermendo:log.mass -0.1052738 0.0435059 -2.419761 0.0171
>
> Correlation:
> (Intr) End_ct lg.mss lg.lfs
> Endo_ectothermendo -0.531
> log.mass -0.348 0.540
> log.lifespan -0.431 -0.033 -0.500
> Endo_ectothermendo:log.mass 0.516 -0.687 -0.805 0.108
>
> Standardized residuals:
> Min Q1 Med Q3 Max
> -3.0213728 -0.4001941 0.2822635 0.7533736 2.3837050
>
> Residual standard error: 0.729365
> Degrees of freedom: 122 total; 117 residual
pagel.model3 <- gls(log(Average_Telomere_Length_kb) ~ Endo_ectotherm + log.mass * log.lifespan, correlation = corPagel(0, phy = pruned_data_tree, form = ~Scientific_name), data = pruned_dat, method = "ML")
summary(pagel.model3)
> Generalized least squares fit by maximum likelihood
> Model: log(Average_Telomere_Length_kb) ~ Endo_ectotherm + log.mass * log.lifespan
> Data: pruned_dat
> AIC BIC logLik
> 240.8611 260.4892 -113.4305
>
> Correlation Structure: corPagel
> Formula: ~Scientific_name
> Parameter estimate(s):
> lambda
> 0.5130464
>
> Coefficients:
> Value Std.Error t-value p-value
> (Intercept) 3.227847 0.5298438 6.092073 0.0000
> Endo_ectothermendo -0.401744 0.3632469 -1.105980 0.2710
> log.mass 0.007697 0.0618546 0.124444 0.9012
> log.lifespan -0.037529 0.1662055 -0.225801 0.8218
> log.mass:log.lifespan -0.013075 0.0166540 -0.785086 0.4340
>
> Correlation:
> (Intr) End_ct lg.mss lg.lfs
> Endo_ectothermendo -0.174
> log.mass -0.578 -0.051
> log.lifespan -0.772 0.014 0.421
> log.mass:log.lifespan 0.684 0.041 -0.903 -0.702
>
> Standardized residuals:
> Min Q1 Med Q3 Max
> -2.8960657 -0.3762918 0.2127450 0.7700036 2.1258145
>
> Residual standard error: 0.7646861
> Degrees of freedom: 122 total; 117 residual
pagel.model4 <- gls(log(Average_Telomere_Length_kb) ~ log.lifespan * Endo_ectotherm * log.mass, correlation = corPagel(0, phy = pruned_data_tree, form = ~Scientific_name), data = pruned_dat, method = "ML")
summary(pagel.model4)
> Generalized least squares fit by maximum likelihood
> Model: log(Average_Telomere_Length_kb) ~ log.lifespan * Endo_ectotherm * log.mass
> Data: pruned_dat
> AIC BIC logLik
> 240.9733 269.0135 -110.4866
>
> Correlation Structure: corPagel
> Formula: ~Scientific_name
> Parameter estimate(s):
> lambda
> 0.4414292
>
> Coefficients:
> Value Std.Error t-value p-value
> (Intercept) 2.9544921 0.7343734 4.023147 0.0001
> log.lifespan -0.1493016 0.3398880 -0.439267 0.6613
> Endo_ectothermendo 0.7884744 1.0325390 0.763627 0.4467
> log.mass -0.0117205 0.1157297 -0.101275 0.9195
> log.lifespan:Endo_ectothermendo -0.1270265 0.4050161 -0.313633 0.7544
> log.lifespan:log.mass 0.0169346 0.0417340 0.405775 0.6857
> Endo_ectothermendo:log.mass -0.0752221 0.1429326 -0.526276 0.5997
> log.lifespan:Endo_ectothermendo:log.mass -0.0065637 0.0472436 -0.138934 0.8897
>
> Correlation:
> (Intr) lg.lfs End_ct lg.mss lg.:E_ lg.l:. End_:.
> log.lifespan -0.850
> Endo_ectothermendo -0.682 0.634
> log.mass -0.563 0.430 0.361
> log.lifespan:Endo_ectothermendo 0.714 -0.838 -0.869 -0.363
> log.lifespan:log.mass 0.704 -0.761 -0.483 -0.873 0.640
> Endo_ectothermendo:log.mass 0.456 -0.348 -0.591 -0.809 0.484 0.707
> log.lifespan:Endo_ectothermendo:log.mass -0.622 0.672 0.694 0.772 -0.766 -0.884 -0.883
>
> Standardized residuals:
> Min Q1 Med Q3 Max
> -3.1311098 -0.4398032 0.2639437 0.6540715 2.3785288
>
> Residual standard error: 0.714069
> Degrees of freedom: 122 total; 114 residual
pagel.model5 <- gls(log(Average_Telomere_Length_kb) ~ log.lifespan + log.mass, correlation = corPagel(0, phy = pruned_data_tree, form = ~Scientific_name), data = pruned_dat, method = "ML")
summary(pagel.model5)
> Generalized least squares fit by maximum likelihood
> Model: log(Average_Telomere_Length_kb) ~ log.lifespan + log.mass
> Data: pruned_dat
> AIC BIC logLik
> 238.6662 252.6863 -114.3331
>
> Correlation Structure: corPagel
> Formula: ~Scientific_name
> Parameter estimate(s):
> lambda
> 0.5375615
>
> Coefficients:
> Value Std.Error t-value p-value
> (Intercept) 3.414242 0.3783179 9.024795 0.0000
> log.lifespan -0.123003 0.1185862 -1.037249 0.3017
> log.mass -0.037411 0.0265794 -1.407516 0.1619
>
> Correlation:
> (Intr) lg.lfs
> log.lifespan -0.560
> log.mass 0.119 -0.697
>
> Standardized residuals:
> Min Q1 Med Q3 Max
> -3.1999393 -0.6749240 -0.1149099 0.4002848 1.7134961
>
> Residual standard error: 0.7831801
> Degrees of freedom: 122 total; 119 residual
pagel.model6 <- gls(log(Average_Telomere_Length_kb) ~ log.lifespan * log.mass, correlation = corPagel(0, phy = pruned_data_tree, form = ~Scientific_name), data = pruned_dat, method = "ML")
summary(pagel.model6)
> Generalized least squares fit by maximum likelihood
> Model: log(Average_Telomere_Length_kb) ~ log.lifespan * log.mass
> Data: pruned_dat
> AIC BIC logLik
> 240.1265 256.9507 -114.0633
>
> Correlation Structure: corPagel
> Formula: ~Scientific_name
> Parameter estimate(s):
> lambda
> 0.5217597
>
> Coefficients:
> Value Std.Error t-value p-value
> (Intercept) 3.1343979 0.5245486 5.975419 0.0000
> log.lifespan -0.0363369 0.1666007 -0.218108 0.8277
> log.mass 0.0036685 0.0619088 0.059256 0.9528
> log.lifespan:log.mass -0.0121864 0.0166738 -0.730868 0.4663
>
> Correlation:
> (Intr) lg.lfs lg.mss
> log.lifespan -0.779
> log.mass -0.595 0.422
> log.lifespan:log.mass 0.701 -0.703 -0.903
>
> Standardized residuals:
> Min Q1 Med Q3 Max
> -3.2569026 -0.6993456 -0.1267147 0.4314327 1.7152585
>
> Residual standard error: 0.7731187
> Degrees of freedom: 122 total; 118 residual
output.models <- model.sel(pagel.model0, pagel.model1, pagel.model2, pagel.model3, pagel.model4, pagel.model5, pagel.model6)
sel.table <- round(as.data.frame(output.models)[9:13], 3)
names(sel.table)[1] <- "K"
sel.table$Model <- rownames(sel.table)
sel.table <- sel.table[ , c(6, 1, 2, 3, 4, 5)]
knitr::kable(sel.table, digits = 3, caption = 'Model selection procedure based on AIC criterion', row.names = FALSE, align = 'l')
Model | K | logLik | AICc | delta | weight |
---|---|---|---|---|---|
pagel.model2 | 7 | -110.848 | 236.678 | 0.000 | 0.448 |
pagel.model1 | 7 | -111.481 | 237.944 | 1.266 | 0.238 |
pagel.model5 | 5 | -114.333 | 239.183 | 2.506 | 0.128 |
pagel.model0 | 6 | -113.744 | 240.219 | 3.541 | 0.076 |
pagel.model6 | 6 | -114.063 | 240.857 | 4.179 | 0.055 |
pagel.model3 | 7 | -113.431 | 241.844 | 5.166 | 0.034 |
pagel.model4 | 10 | -110.487 | 242.955 | 6.277 | 0.019 |
## Estimating lambda from PGLS models
pagel.model0.8 <- gls(log(Average_Telomere_Length_kb) ~ Endo_ectotherm * log.mass + log.lifespan, correlation = corPagel(0.8, phy = pruned_data_tree, form = ~Scientific_name, fixed = TRUE), data = pruned_dat, method = "ML")
summary(pagel.model0.8)
> Generalized least squares fit by maximum likelihood
> Model: log(Average_Telomere_Length_kb) ~ Endo_ectotherm * log.mass + log.lifespan
> Data: pruned_dat
> AIC BIC logLik
> 240.666 257.4901 -114.333
>
> Correlation Structure: corPagel
> Formula: ~Scientific_name
> Parameter estimate(s):
> lambda
> 0.8
>
> Coefficients:
> Value Std.Error t-value p-value
> (Intercept) 3.201521 0.5778259 5.540632 0.0000
> Endo_ectothermendo 0.237381 0.6632568 0.357902 0.7211
> log.mass 0.036292 0.0501916 0.723071 0.4711
> log.lifespan -0.179061 0.1275018 -1.404384 0.1629
> Endo_ectothermendo:log.mass -0.093997 0.0506152 -1.857091 0.0658
>
> Correlation:
> (Intr) End_ct lg.mss lg.lfs
> Endo_ectothermendo -0.448
> log.mass -0.357 0.459
> log.lifespan -0.354 -0.007 -0.467
> Endo_ectothermendo:log.mass 0.475 -0.573 -0.830 0.117
>
> Standardized residuals:
> Min Q1 Med Q3 Max
> -2.2119959 -0.3002200 0.1898719 0.5320637 1.7384591
>
> Residual standard error: 1.000879
> Degrees of freedom: 122 total; 117 residual
pagel.model0 <- gls(log(Average_Telomere_Length_kb) ~ Endo_ectotherm * log.mass + log.lifespan, correlation = corPagel(0, phy = pruned_data_tree, form = ~Scientific_name, fixed = TRUE), data = pruned_dat, method = "ML")
summary(pagel.model0)
> Generalized least squares fit by maximum likelihood
> Model: log(Average_Telomere_Length_kb) ~ Endo_ectotherm * log.mass + log.lifespan
> Data: pruned_dat
> AIC BIC logLik
> 260.5828 277.4069 -124.2914
>
> Correlation Structure: corPagel
> Formula: ~Scientific_name
> Parameter estimate(s):
> lambda
> 0
>
> Coefficients:
> Value Std.Error t-value p-value
> (Intercept) 2.2828151 0.3338815 6.837201 0.0000
> Endo_ectothermendo 0.9867956 0.3490592 2.827015 0.0055
> log.mass 0.0789860 0.0449376 1.757682 0.0814
> log.lifespan -0.1441376 0.1110251 -1.298243 0.1968
> Endo_ectothermendo:log.mass -0.0989801 0.0444715 -2.225698 0.0280
>
> Correlation:
> (Intr) End_ct lg.mss lg.lfs
> Endo_ectothermendo -0.617
> log.mass -0.428 0.771
> log.lifespan -0.477 -0.256 -0.507
> Endo_ectothermendo:log.mass 0.586 -0.893 -0.847 0.191
>
> Standardized residuals:
> Min Q1 Med Q3 Max
> -3.60527368 -0.60608579 -0.01119332 0.60835477 2.26235421
>
> Residual standard error: 0.6702151
> Degrees of freedom: 122 total; 117 residual
intervals(pagel.model0, which = 'var-cov')
> Approximate 95% confidence intervals
>
> Residual standard error:
> lower est. upper
> 0.5956358 0.6702151 0.7663126
pagel.model0.5 <- gls(log(Average_Telomere_Length_kb) ~ Endo_ectotherm * log.mass + log.lifespan, correlation = corPagel(0.5, phy = pruned_data_tree, form = ~Scientific_name, fixed = TRUE), data = pruned_dat, method = "ML")
summary(pagel.model0.5)
> Generalized least squares fit by maximum likelihood
> Model: log(Average_Telomere_Length_kb) ~ Endo_ectotherm * log.mass + log.lifespan
> Data: pruned_dat
> AIC BIC logLik
> 233.7381 250.5622 -110.869
>
> Correlation Structure: corPagel
> Formula: ~Scientific_name
> Parameter estimate(s):
> lambda
> 0.5
>
> Coefficients:
> Value Std.Error t-value p-value
> (Intercept) 2.9683261 0.4366935 6.797275 0.0000
> Endo_ectothermendo 0.3837552 0.4755101 0.807039 0.4213
> log.mass 0.0484022 0.0438711 1.103282 0.2722
> log.lifespan -0.1582973 0.1162848 -1.361289 0.1760
> Endo_ectothermendo:log.mass -0.1045713 0.0438371 -2.385452 0.0187
>
> Correlation:
> (Intr) End_ct lg.mss lg.lfs
> Endo_ectothermendo -0.524
> log.mass -0.348 0.533
> log.lifespan -0.426 -0.030 -0.499
> Endo_ectothermendo:log.mass 0.513 -0.678 -0.807 0.109
>
> Standardized residuals:
> Min Q1 Med Q3 Max
> -2.9670009 -0.3917590 0.2693331 0.7427991 2.3437865
>
> Residual standard error: 0.7424674
> Degrees of freedom: 122 total; 117 residual
intervals(pagel.model0.5, which = 'var-cov')
> Approximate 95% confidence intervals
>
> Residual standard error:
> lower est. upper
> 0.6598481 0.7424674 0.8489247
pagel.model1 <- gls(log(Average_Telomere_Length_kb) ~ Endo_ectotherm * log.mass + log.lifespan, correlation = corPagel(1, phy = pruned_data_tree, form = ~Scientific_name, fixed = TRUE), data = pruned_dat, method = "ML")
summary(pagel.model1)
> Generalized least squares fit by maximum likelihood
> Model: log(Average_Telomere_Length_kb) ~ Endo_ectotherm * log.mass + log.lifespan
> Data: pruned_dat
> AIC BIC logLik
> 282.7728 299.5969 -135.3864
>
> Correlation Structure: corPagel
> Formula: ~Scientific_name
> Parameter estimate(s):
> lambda
> 1
>
> Coefficients:
> Value Std.Error t-value p-value
> (Intercept) 3.477902 1.0698466 3.250842 0.0015
> Endo_ectothermendo 0.083476 1.3090875 0.063767 0.9493
> log.mass 0.019098 0.0736050 0.259463 0.7957
> log.lifespan -0.212424 0.1406667 -1.510120 0.1337
> Endo_ectothermendo:log.mass -0.077842 0.0773762 -1.006014 0.3165
>
> Correlation:
> (Intr) End_ct lg.mss lg.lfs
> Endo_ectothermendo -0.371
> log.mass -0.410 0.395
> log.lifespan -0.220 0.000 -0.329
> Endo_ectothermendo:log.mass 0.436 -0.453 -0.881 0.099
>
> Standardized residuals:
> Min Q1 Med Q3 Max
> -1.10748607 -0.15843091 0.07926082 0.26006154 0.86623002
>
> Residual standard error: 2.008683
> Degrees of freedom: 122 total; 117 residual
intervals(pagel.model1, which = 'var-cov')
> Approximate 95% confidence intervals
>
> Residual standard error:
> lower est. upper
> 1.785163 2.008683 2.296694
output.models <- model.sel(pagel.model0.8, pagel.model0, pagel.model0.5, pagel.model1)
sel.table <- round(as.data.frame(output.models)[7:11], 3)
names(sel.table)[1] <- "K"
sel.table$Model <- rownames(sel.table)
sel.table <- sel.table[ , c(6, 1, 2, 3, 4, 5)]
knitr::kable(sel.table, digits = 3, caption = 'Model selection procedure based on AIC criterion', row.names = FALSE, align = 'l')
Model | K | logLik | AICc | delta | weight |
---|---|---|---|---|---|
pagel.model0.5 | 6 | -110.869 | 234.469 | 0.000 | 0.97 |
pagel.model0.8 | 6 | -114.333 | 241.396 | 6.928 | 0.03 |
pagel.model0 | 6 | -124.291 | 261.313 | 26.845 | 0.00 |
pagel.model1 | 6 | -135.386 | 283.503 | 49.035 | 0.00 |
pruned_dat$Endo_ectotherm <- as.factor(pruned_dat$Endo_ectotherm)
mod.plot <- gls(log(Average_Telomere_Length_kb) ~ Endo_ectotherm * log.mass, correlation = corPagel(0.5, phy = pruned_data_tree, form = ~Scientific_name, fixed = TRUE), data = pruned_dat, method = "ML")
summary(mod.plot)
> Generalized least squares fit by maximum likelihood
> Model: log(Average_Telomere_Length_kb) ~ Endo_ectotherm * log.mass
> Data: pruned_dat
> AIC BIC logLik
> 233.6552 247.6753 -111.8276
>
> Correlation Structure: corPagel
> Formula: ~Scientific_name
> Parameter estimate(s):
> lambda
> 0.5
>
> Coefficients:
> Value Std.Error t-value p-value
> (Intercept) 2.7150448 0.3964989 6.847547 0.0000
> Endo_ectothermendo 0.3642954 0.4770102 0.763706 0.4466
> log.mass 0.0186163 0.0381623 0.487818 0.6266
> Endo_ectothermendo:log.mass -0.0980766 0.0437340 -2.242573 0.0268
>
> Correlation:
> (Intr) End_ct lg.mss
> Endo_ectothermendo -0.594
> log.mass -0.715 0.598
> Endo_ectothermendo:log.mass 0.622 -0.679 -0.873
>
> Standardized residuals:
> Min Q1 Med Q3 Max
> -3.0262099 -0.4803355 0.1497991 0.6394544 2.3543177
>
> Residual standard error: 0.7483241
> Degrees of freedom: 122 total; 118 residual
anova(mod.plot, pagel.model0.5) ## Given that these models do not differ from each other, we are going to use mod.plot for visualization purposes
> Model df AIC BIC logLik Test L.Ratio p-value
> mod.plot 1 5 233.6552 247.6753 -111.8276
> pagel.model0.5 2 6 233.7381 250.5622 -110.8690 1 vs 2 1.917158 0.1662
pred.mod <- data.frame(log.mass = seq(min(pruned_dat$log.mass), max(pruned_dat$log.mass), len = 122), Endo_ectotherm = pruned_dat$Endo_ectotherm, row.names = rownames(pruned_dat))
pred.mod$tl.lg <- predict(mod.plot, pred.mod, type = 'response', se = TRUE)$fit
pred.mod$se <- predict(mod.plot, pred.mod, type = 'response', se = TRUE)$se.fit
str(pred.mod)
> 'data.frame': 122 obs. of 4 variables:
> $ log.mass : num 0.631 0.778 0.925 1.072 1.219 ...
> $ Endo_ectotherm: Factor w/ 2 levels "ecto","endo": 2 2 2 2 2 2 2 1 2 2 ...
> $ tl.lg : num 3.03 3.02 3.01 2.99 2.98 ...
> $ se : num 0.395 0.394 0.393 0.392 0.391 ...
ecto <- pred.mod[pruned_dat$Endo_ectotherm == 'ecto', ]
endo <- pred.mod[pruned_dat$Endo_ectotherm == 'endo', ]
pred.mod
> log.mass Endo_ectotherm tl.lg se
> Hirundo_rustica 0.6312718 endo 3.029179 0.3950648
> Accipiter_gentilis 0.7782917 endo 3.017497 0.3939497
> Amazona_amazonica 0.9253116 endo 3.005815 0.3928565
> Buteo_jamaicensis 1.0723315 endo 2.994132 0.3917853
> Buteo_swainsoni 1.2193514 endo 2.982450 0.3907363
> Chrysolophus_pictus 1.3663713 endo 2.970768 0.3897096
> Colinus_virginianus 1.5133912 endo 2.959086 0.3887055
> Dicentrarchus_labrax 1.6604111 ecto 2.745955 0.3539540
> Diomedea_exulans 1.8074310 endo 2.935721 0.3867656
> Falco_sparverius 1.9544510 endo 2.924039 0.3858302
> Haliaeetus_leucocephalus 2.1014709 endo 2.912357 0.3849180
> Macronectes_giganteus 2.2484908 endo 2.900674 0.3840293
> Macronectes_halli 2.3955107 endo 2.888992 0.3831640
> Meleagris_gallopavo 2.5425306 endo 2.877310 0.3823225
> Rissa_tridactyla 2.6895505 endo 2.865628 0.3815049
> Strigops_habroptila 2.8365704 endo 2.853945 0.3807114
> Tachymarptis_melba 2.9835903 endo 2.842263 0.3799420
> Pseudocaranx_wrighti 3.1306102 ecto 2.773325 0.3220499
> Cyprinus_carpio 3.2776301 ecto 2.776062 0.3192267
> Lutjanus_argentimaculatus 3.4246500 ecto 2.778799 0.3164778
> Upeneichthys_vlamingii 3.5716700 ecto 2.781536 0.3138051
> Acanthopagrus_schlegelii 3.7186899 ecto 2.784273 0.3112106
> Macquaria_ambigua 3.8657098 ecto 2.787010 0.3086963
> Nothobranchius_furzeri 4.0127297 ecto 2.789747 0.3062642
> Nothobranchius_rachovii 4.1597496 ecto 2.792484 0.3039162
> Gadus_morhua 4.3067695 ecto 2.795221 0.3016542
> Platycephalus_bassensis 4.4537894 ecto 2.797958 0.2994804
> Oncorhynchus_mykiss 4.6008093 ecto 2.800695 0.2973965
> Neoceratodus_forsteri 4.7478292 ecto 2.803432 0.2954044
> Urolophus_paucimaculatus 4.8948491 ecto 2.806169 0.2935061
> Callorhinchus_milii 5.0418690 ecto 2.808906 0.2917034
> Meriones_unguiculatus 5.1888890 endo 2.667029 0.3713942
> Chinchilla_lanigera 5.3359089 endo 2.655347 0.3710291
> Ondatra_zibethicus 5.4829288 endo 2.643665 0.3706901
> Mesocricetus_auratus 5.6299487 endo 2.631983 0.3703773
> Myocastor_coypus 5.7769686 endo 2.620300 0.3700908
> Marmota_monax 5.9239885 endo 2.608618 0.3698307
> Tamias_striatus 6.0710084 endo 2.596936 0.3695969
> Zalophus_californianus 6.2180283 endo 2.585254 0.3693895
> Castor_canadensis 6.3650482 endo 2.573571 0.3692086
> Ateles_geoffroyi 6.5120681 endo 2.561889 0.3690542
> Crocuta_crocuta 6.6590880 endo 2.550207 0.3689264
> Aplodontia_rufa 6.8061080 endo 2.538525 0.3688252
> Balaena_mysticetus 6.9531279 endo 2.526842 0.3687505
> Homo_sapiens 7.1001478 endo 2.515160 0.3687025
> Peromyscus_maniculatus 7.2471677 endo 2.503478 0.3686811
> Pteropus_rodricensis 7.3941876 endo 2.491796 0.3686863
> Saimiri_sciureus 7.5412075 endo 2.480113 0.3687182
> Ceratotherium_simum 7.6882274 endo 2.468431 0.3687767
> Giraffa_camelopardalis 7.8352473 endo 2.456749 0.3688617
> Hydrochoerus_hydrochaeris 7.9822672 endo 2.445067 0.3689734
> Pan_paniscus 8.1292871 endo 2.433384 0.3691117
> Pongo_pygmaeus 8.2763070 endo 2.421702 0.3692765
> Pan_troglodytes 8.4233269 endo 2.410020 0.3694677
> Equus_grevyi 8.5703469 endo 2.398338 0.3696855
> Myrmecophaga_tridactyla 8.7173668 endo 2.386655 0.3699296
> Tapirus_indicus 8.8643867 endo 2.374973 0.3702002
> Ursus_maritimus 9.0114066 endo 2.363291 0.3704970
> Chaetophractus_vellerosus 9.1584265 endo 2.351609 0.3708200
> Eschrichtius_robustus 9.3054464 endo 2.339926 0.3711693
> Loxodonta_africana 9.4524663 endo 2.328244 0.3715446
> Muntiacus_muntjak 9.5994862 endo 2.316562 0.3719460
> Muntiacus_reevesi 9.7465061 endo 2.304880 0.3723733
> Elephas_maximus 9.8935260 endo 2.293197 0.3728264
> Procavia_capensis 10.0405459 endo 2.281515 0.3733053
> Tupaia_tana 10.1875659 endo 2.269833 0.3738098
> Heterocephalus_glaber 10.3345858 endo 2.258151 0.3743399
> Macaca_mulatta 10.4816057 endo 2.246468 0.3748954
> Choloepus_hoffmanni 10.6286256 endo 2.234786 0.3754763
> Tursiops_truncatus 10.7756455 endo 2.223104 0.3760824
> Lemur_catta 10.9226654 endo 2.211422 0.3767135
> Ochotona_princeps 11.0696853 endo 2.199739 0.3773696
> Ailurus_fulgens 11.2167052 endo 2.188057 0.3780506
> Tadarida_brasiliensis 11.3637251 endo 2.176375 0.3787562
> Myotis_lucifugus 11.5107450 endo 2.164693 0.3794864
> Didelphis_virginiana 11.6577649 endo 2.153010 0.3802411
> Galegeeska_rufescens 11.8047849 endo 2.141328 0.3810200
> Macroscelides_proboscideus 11.9518048 endo 2.129646 0.3818230
> Atelerix_albiventris 12.0988247 endo 2.117964 0.3826500
> Lepus_californicus 12.2458446 endo 2.106281 0.3835008
> Oryctolagus_cuniculus 12.3928645 endo 2.094599 0.3843753
> Sylvilagus_aquaticus 12.5398844 endo 2.082917 0.3852733
> Panthera_tigris 12.6869043 endo 2.071235 0.3861946
> Sciurus_carolinensis 12.8339242 endo 2.059552 0.3871391
> Setifer_setosus 12.9809441 endo 2.047870 0.3881066
> Alligator_sinensis 13.1279640 ecto 2.959438 0.3521694
> Zootoca_vivipara 13.2749839 ecto 2.962175 0.3556599
> Liasis_fuscus 13.4220039 ecto 2.964912 0.3592041
> Trachemys_scripta 13.5690238 ecto 2.967649 0.3628005
> Taeniopygia_guttata 13.7160437 endo 1.989459 0.3932830
> Aphelocoma_coerulescens 13.8630636 endo 1.977777 0.3943848
> Aphelocoma_ultramarina 14.0100835 endo 1.966094 0.3955084
> Branta_leucopsis 14.1571034 endo 1.954412 0.3966535
> Calidris_alpina 14.3041233 endo 1.942730 0.3978200
> Calonectris_diomedea 14.4511432 endo 1.931048 0.3990078
> Cepphus_grylle 14.5981631 endo 1.919365 0.4002165
> Fregata_minor 14.7451830 endo 1.907683 0.4014460
> Fulmarus_glacialis 14.8922029 endo 1.896001 0.4026962
> Haematopus_ostralegus 15.0392228 endo 1.884319 0.4039668
> Larus_crassirostris 15.1862428 endo 1.872636 0.4052577
> Lonchura_striata 15.3332627 endo 1.860954 0.4065686
> Oceanodroma_leucorhoa 15.4802826 endo 1.849272 0.4078994
> Parus_major 15.6273025 endo 1.837590 0.4092498
> Passerculus_sandwichensis 15.7743224 endo 1.825907 0.4106197
> Pygoscelis_adeliae 15.9213423 endo 1.814225 0.4120089
> Riparia_riparia 16.0683622 endo 1.802543 0.4134171
> Sterna_hirundo 16.2153821 endo 1.790861 0.4148443
> Sula_sula 16.3624020 endo 1.779178 0.4162901
> Tachycineta_albilinea 16.5094219 endo 1.767496 0.4177544
> Tachycineta_bicolor 16.6564418 endo 1.755814 0.4192371
> Turdus_merula 16.8034618 endo 1.744132 0.4207378
> Uria_lomvia 16.9504817 endo 1.732449 0.4222565
> Vireo_olivaceus 17.0975016 endo 1.720767 0.4237929
> Lacerta_agilis 17.2445215 ecto 3.036073 0.4658332
> Alligator_mississippiensis 17.3915414 ecto 3.038810 0.4703553
> Xiphophorus_maculatus 17.5385613 ecto 3.041547 0.4749006
> Xiphophorus_hellerii 17.6855812 ecto 3.044284 0.4794685
> Danio_rerio 17.8326011 ecto 3.047021 0.4840582
> Macaca_nemestrina 17.9796210 endo 1.650674 0.4333728
> Macaca_fascicularis 18.1266409 endo 1.638991 0.4350279
> Gorilla_gorilla 18.2736608 endo 1.627309 0.4366993
> Emys_orbicularis 18.4206808 ecto 3.057969 0.5026246
cols <- c('purple', 'orange')
##png('figure2.png', width = 7, height = 7, units = 'in', res = 360)
plot(log(Average_Telomere_Length_kb) ~ log.mass, data = pruned_dat, pch = 21, bg = cols[pruned_dat$Endo_ectotherm], col = 'black', las = 1, xlab = "Mass log(gr)", ylab = "Telomere length log(kb)", type = 'n')
grid(nx = NULL, ny = NULL, col = "lightgray", lwd = 1)
par(new = TRUE)
plot(log(Average_Telomere_Length_kb) ~ log.mass, data = pruned_dat, pch = 21, bg = cols[pruned_dat$Endo_ectotherm], col = 'black', las = 1, xlab = "Mass log(gr)", ylab = "Telomere length log(kb)")
lines(ecto$tl.lg ~ ecto$log.mass, data = ecto, lwd = 2.5, col = 'purple')
polygon(c(ecto$log.mass, rev(ecto$log.mass)), c(ecto$tl.lg+ecto$se, rev(ecto$tl.lg-ecto$se)), border = FALSE, col = alpha('purple', 0.2))
lines(endo$tl.lg ~ endo$log.mass, data = endo, lwd = 2.5, col = 'orange')
polygon(c(endo$log.mass, rev(endo$log.mass)), c(endo$tl.lg+endo$se, rev(endo$tl.lg-endo$se)), border = FALSE, col = alpha('orange', 0.2))
legend('bottomleft', legend = c('Ectotherms', 'Endotherms'), pch = 16, col = c('purple', 'orange'), lwd = 1, bty = 'n', cex = 0.8)
##dev.off()
pruned_dat$Telomerase_activity[pruned_dat$Telomerase_activity == 0] <- "absent"
pruned_dat$Telomerase_activity[pruned_dat$Telomerase_activity == 1] <- "present"
pruned_dat$Telomerase_activity[is.na(pruned_dat$Telomerase_activity)] <- "N/A"
tel.act <- setNames(pruned_dat$Telomerase_activity, rownames(pruned_dat))
tel.act
> Hirundo_rustica Accipiter_gentilis Amazona_amazonica
> "N/A" "N/A" "N/A"
> Buteo_jamaicensis Buteo_swainsoni Chrysolophus_pictus
> "N/A" "N/A" "N/A"
> Colinus_virginianus Dicentrarchus_labrax Diomedea_exulans
> "N/A" "N/A" "N/A"
> Falco_sparverius Haliaeetus_leucocephalus Macronectes_giganteus
> "N/A" "N/A" "N/A"
> Macronectes_halli Meleagris_gallopavo Rissa_tridactyla
> "N/A" "N/A" "N/A"
> Strigops_habroptila Tachymarptis_melba Pseudocaranx_wrighti
> "N/A" "N/A" "N/A"
> Cyprinus_carpio Lutjanus_argentimaculatus Upeneichthys_vlamingii
> "N/A" "N/A" "N/A"
> Acanthopagrus_schlegelii Macquaria_ambigua Nothobranchius_furzeri
> "N/A" "N/A" "present"
> Nothobranchius_rachovii Gadus_morhua Platycephalus_bassensis
> "N/A" "present" "N/A"
> Oncorhynchus_mykiss Neoceratodus_forsteri Urolophus_paucimaculatus
> "N/A" "N/A" "N/A"
> Callorhinchus_milii Meriones_unguiculatus Chinchilla_lanigera
> "N/A" "present" "present"
> Ondatra_zibethicus Mesocricetus_auratus Myocastor_coypus
> "present" "present" "present"
> Marmota_monax Tamias_striatus Zalophus_californianus
> "present" "present" "absent"
> Castor_canadensis Ateles_geoffroyi Crocuta_crocuta
> "absent" "absent" "absent"
> Aplodontia_rufa Balaena_mysticetus Homo_sapiens
> "absent" "absent" "absent"
> Peromyscus_maniculatus Pteropus_rodricensis Saimiri_sciureus
> "present" "absent" "absent"
> Ceratotherium_simum Giraffa_camelopardalis Hydrochoerus_hydrochaeris
> "absent" "absent" "present"
> Pan_paniscus Pongo_pygmaeus Pan_troglodytes
> "absent" "absent" "N/A"
> Equus_grevyi Myrmecophaga_tridactyla Tapirus_indicus
> "absent" "absent" "absent"
> Ursus_maritimus Chaetophractus_vellerosus Eschrichtius_robustus
> "absent" "absent" "absent"
> Loxodonta_africana Muntiacus_muntjak Muntiacus_reevesi
> "absent" "absent" "absent"
> Elephas_maximus Procavia_capensis Tupaia_tana
> "absent" "absent" "absent"
> Heterocephalus_glaber Macaca_mulatta Choloepus_hoffmanni
> "present" "absent" "absent"
> Tursiops_truncatus Lemur_catta Ochotona_princeps
> "absent" "absent" "present"
> Ailurus_fulgens Tadarida_brasiliensis Myotis_lucifugus
> "absent" "present" "present"
> Didelphis_virginiana Galegeeska_rufescens Macroscelides_proboscideus
> "present" "present" "present"
> Atelerix_albiventris Lepus_californicus Oryctolagus_cuniculus
> "present" "absent" "absent"
> Sylvilagus_aquaticus Panthera_tigris Sciurus_carolinensis
> "absent" "present" "present"
> Setifer_setosus Alligator_sinensis Zootoca_vivipara
> "present" "absent" "N/A"
> Liasis_fuscus Trachemys_scripta Taeniopygia_guttata
> "N/A" "N/A" "N/A"
> Aphelocoma_coerulescens Aphelocoma_ultramarina Branta_leucopsis
> "N/A" "N/A" "N/A"
> Calidris_alpina Calonectris_diomedea Cepphus_grylle
> "N/A" "N/A" "N/A"
> Fregata_minor Fulmarus_glacialis Haematopus_ostralegus
> "N/A" "N/A" "N/A"
> Larus_crassirostris Lonchura_striata Oceanodroma_leucorhoa
> "N/A" "N/A" "N/A"
> Parus_major Passerculus_sandwichensis Pygoscelis_adeliae
> "N/A" "N/A" "N/A"
> Riparia_riparia Sterna_hirundo Sula_sula
> "N/A" "N/A" "N/A"
> Tachycineta_albilinea Tachycineta_bicolor Turdus_merula
> "N/A" "N/A" "N/A"
> Uria_lomvia Vireo_olivaceus Lacerta_agilis
> "N/A" "N/A" "N/A"
> Alligator_mississippiensis Xiphophorus_maculatus Xiphophorus_hellerii
> "N/A" "N/A" "N/A"
> Danio_rerio Macaca_nemestrina Macaca_fascicularis
> "present" "N/A" "N/A"
> Gorilla_gorilla Emys_orbicularis
> "N/A" "N/A"
TA <- to.matrix(tel.act, unique(tel.act))
TA <- TA[pruned_data_tree$tip.label, ]
life.span <- setNames(pruned_dat$log.lifespan, rownames(pruned_dat))
log_mass <- setNames(pruned_dat$log.mass, rownames(pruned_dat))
telo.length <- setNames(log(pruned_dat$Average_Telomere_Length_kb), rownames(pruned_dat))
plotTree(pruned_data_tree, ftype = "off", mar = c(3, 2, 2, 3))
tiplabels(pie = TA, piecol = c("white", "gray", "black"), cex = 0.22, offset = 4.3)
par(xpd = TRUE)
legend(x = 150, y = 0.2, legend = unique(tel.act), pch = 21, pt.bg = c("white", "gray", "black"), pt.cex = 1, bty = "n", title = "Telomerase activity", cex = 0.7, horiz = TRUE)
par(new = TRUE)
par(mar = c(3, 32, 2, 1.1))
barplot(life.span[pruned_data_tree$tip.label], horiz = TRUE, width = 1, space = 0,
ylim = c(1, length(pruned_data_tree$tip.label))-0.5, names = "", las = 2, cex.axis = 0.5, axes = FALSE)
axis(1, at = round(seq(min(life.span), max(life.span), 1.5), 1), labels = FALSE)
text(round(seq(min(life.span), max(life.span), 1.5), 1), par("usr")[3] - 0.2, labels = round(seq(min(life.span), max(life.span), 1.5), 1), srt = 50, pos = 1, xpd = TRUE, cex = 0.5, offset = 1)
mtext("Lifespan \n (years)", side = 1, line = 1.6, cex = 0.5, font = 2)
## Ancestral state reconstruction of telomere size
fit <- fastAnc(pruned_data_tree, telo.length, vars = TRUE, CI = TRUE)
fit$CI[1, ]
> [1] 1.182278 4.654196
obj <- contMap(pruned_data_tree, telo.length, plot = FALSE)
Figure 1
##png("figure1.png", width = 7, height = 7, units = "in", res = 360)
##pdf("figure1.pdf")
plot(obj, ftype = "off", legend = FALSE, ylim = c(1-0.09*(Ntip(obj$tree)-1), Ntip(obj$tree)), mar = c(1, 0.1, 1, 4), lwd = 1.5)
add.color.bar(150, obj$cols,title = "Log telomere length (kb)", lims = obj$lims, digits = 3, prompt = FALSE, x = 0, y = 1-0.08*(Ntip(obj$tree)-1), lwd = 4, fsize = 0.6, subtitle = "")
par(xpd = TRUE)
text(300, 118, 'Testudines')
text(300, 100.5, 'Aves', col = 'red')
text(300, 82, 'Crocodilia')
text(240, 73, 'Squamata')
text(240, 39, 'Mammalia', col = 'red')
text(160, 15, 'Osteichthyes')
text(160, 4.5, 'Chondrichthyes')
#cladelabels(pruned_data_tree, node = 217, "Ectotherms", offset = 6)
#cladelabels(pruned_data_tree, node = 153, "Endotherms", offset = 6)
#segments(518, 0, 518, 18)
#segments(518, 0, 508, 0)
#segments(518, 18, 508, 18)
#text(528, 9, 'Ectotherms', srt = 90)
tiplabels(pie = TA, piecol = c("gray", "white", "black"), cex = 0.16, offset = 5.7)
legend(x = 200, y = -5, legend = unique(tel.act), pch = 21, pt.bg = c("gray", "white", "black"), pt.cex = 1, bty = "n", title = "Telomerase activity", cex = 0.7, horiz = TRUE)
par(new = TRUE)
par(mar = c(3.6, 30.8, 3, 2.2))
barplot(life.span[pruned_data_tree$tip.label], horiz = TRUE, width = 1.07, space = 0,
ylim = c(1, length(pruned_data_tree$tip.label))-0.5, names = "", las = 2, cex.axis = 0.5, axes = FALSE)
axis(1, at = round(seq(min(life.span), max(life.span), 1.5), 1), labels = FALSE)
text(round(seq(min(life.span), max(life.span), 1.5), 1), par("usr")[3] - 0.2, labels = round(seq(min(life.span), max(life.span), 1.5), 1), srt = 50, pos = 1, xpd = TRUE, cex = 0.5, offset = 1)
mtext("Log lifespan \n (years)", side = 1, line = 1.6, cex = 0.5, font = 2)
##dev.off()
## Correlated evolution under the threshold model
## Removing NAs from the dataset
pruned_dat$Telomerase_activity
> [1] "N/A" "N/A" "N/A" "N/A" "N/A" "N/A" "N/A" "N/A" "N/A" "N/A"
> [11] "N/A" "N/A" "N/A" "N/A" "N/A" "N/A" "N/A" "N/A" "N/A" "N/A"
> [21] "N/A" "N/A" "N/A" "present" "N/A" "present" "N/A" "N/A" "N/A" "N/A"
> [31] "N/A" "present" "present" "present" "present" "present" "present" "present" "absent" "absent"
> [41] "absent" "absent" "absent" "absent" "absent" "present" "absent" "absent" "absent" "absent"
> [51] "present" "absent" "absent" "N/A" "absent" "absent" "absent" "absent" "absent" "absent"
> [61] "absent" "absent" "absent" "absent" "absent" "absent" "present" "absent" "absent" "absent"
> [71] "absent" "present" "absent" "present" "present" "present" "present" "present" "present" "absent"
> [81] "absent" "absent" "present" "present" "present" "absent" "N/A" "N/A" "N/A" "N/A"
> [91] "N/A" "N/A" "N/A" "N/A" "N/A" "N/A" "N/A" "N/A" "N/A" "N/A"
> [101] "N/A" "N/A" "N/A" "N/A" "N/A" "N/A" "N/A" "N/A" "N/A" "N/A"
> [111] "N/A" "N/A" "N/A" "N/A" "N/A" "N/A" "N/A" "present" "N/A" "N/A"
> [121] "N/A" "N/A"
pruned_dat_not_NAs <- pruned_dat[!pruned_dat$Telomerase_activity == "N/A", ]
pruned_dat_not_NAs$Telomerase_activity
> [1] "present" "present" "present" "present" "present" "present" "present" "present" "present" "absent"
> [11] "absent" "absent" "absent" "absent" "absent" "absent" "present" "absent" "absent" "absent"
> [21] "absent" "present" "absent" "absent" "absent" "absent" "absent" "absent" "absent" "absent"
> [31] "absent" "absent" "absent" "absent" "absent" "absent" "present" "absent" "absent" "absent"
> [41] "absent" "present" "absent" "present" "present" "present" "present" "present" "present" "absent"
> [51] "absent" "absent" "present" "present" "present" "absent" "present"
check2 <- name.check(pruned_data_tree, pruned_dat_not_NAs)
rm_phy2 <- check2$tree_not_data
rm_dat2 <- check2$data_not_tree
pruned_data_tree_not_NAs <- drop.tip(pruned_data_tree, rm_phy2)
pruned_dat_not_NAs <- subset(pruned_dat_not_NAs, subset = pruned_dat_not_NAs$Scientific_name %in% pruned_data_tree_not_NAs$tip, select = names(pruned_dat_not_NAs))
pruned_dat_not_NAs$Telomerase_activity <- as.factor(pruned_dat_not_NAs$Telomerase_activity)
name.check(pruned_data_tree_not_NAs, pruned_dat_not_NAs)
> [1] "OK"
## Set the number of generations
ngen <- 5e6
## Run MCMC
pruned_dat_not_NAs$Average_Telomere_Length_kb <- log(pruned_dat_not_NAs$Average_Telomere_Length_kb)
mcmc.model <- threshBayes(pruned_data_tree_not_NAs, pruned_dat_not_NAs[ , c(14, 15)], type = c("cont", "disc"), ngen = ngen, plot = FALSE, control = list(print.interval = 5e+05))
> Starting MCMC....
> generation: 500000; mean acceptance rate: 0.23
> generation: 1000000; mean acceptance rate: 0.26
> generation: 1500000; mean acceptance rate: 0.23
> generation: 2000000; mean acceptance rate: 0.22
> generation: 2500000; mean acceptance rate: 0.2
> generation: 3000000; mean acceptance rate: 0.24
> generation: 3500000; mean acceptance rate: 0.24
> generation: 4000000; mean acceptance rate: 0.23
> generation: 4500000; mean acceptance rate: 0.22
> generation: 5000000; mean acceptance rate: 0.24
> Done MCMC.
## Pull out the post burn-in sample and compute HPD
r.mcmc <- tail(mcmc.model$par$r, 0.8*nrow(mcmc.model$par))
class(r.mcmc) <- "mcmc"
hpd.r <- HPDinterval(r.mcmc)
hpd.r
> lower upper
> var1 0.1833235 0.7869591
> attr(,"Probability")
> [1] 0.9500012
Figure S3
## Profile plots from a Bayesian MCMC analysis of the threshold model
#png("figureS3.png", width = 7, height = 7, units = "in", res = 360)
#pdf("figureS3.pdf")
layout(matrix(c(0, 0, 0, 0,
1, 1, 1, 1,
1, 1, 1, 1,
2, 2, 2, 2,
2, 2, 2, 2,
0, 0, 0, 0), nrow = 6, ncol = 4, byrow = TRUE))
plot(mcmc.model$par$logL ~ mcmc.model$par$gen, col = 'gray', type = 'n', ylab = 'Log(L)', xlab = 'Generation', las = 1)
grid()
par(new = TRUE)
plot(mcmc.model$par$logL ~ mcmc.model$par$gen, col = 'gray', type = 'l', ylab = 'Log(L)', xlab = 'Generation', las = 1)
mtext('(a)', side = 2, line = 1.5, at = -160, las = 1)
plot(mcmc.model$par$r ~ mcmc.model$par$gen, col = 'purple', type = 'n', ylab = 'r', xlab = 'Generation', las = 1)
grid()
par(new = TRUE)
plot(mcmc.model$par$r ~ mcmc.model$par$gen, col = 'purple', type = 'l', ylab = 'r', xlab = 'Generation', las = 1)
mtext('(b)', side = 2, line = 1.5, at = 1.2, las = 1)
#dev.off()
Figure 4
## Plot posterior density
#png("figure4.png", width = 7, height = 7, units = "in", res = 360)
#pdf("figure4.pdf")
par(las = 1)
plot(NA, xlim = c(-1, 1.5), ylim = c(0, 3), axes = FALSE, xlab = '', ylab = '')
grid()
par(new = TRUE)
plot(density(mcmc.model), xlim = c(-1, 1.5))
box()
## add whiskers to show HPD
h <- 0-par()$usr[3]
lines(x = hpd.r, y = rep(-h/2, 2))
lines(x = rep(hpd.r[1], 2), y = c(-0.3, -0.7)*h)
lines(x = rep(hpd.r[2], 2), y = c(-0.3, -0.7)*h)
#dev.off()