Assess factors shaping the evolution of duettting in owls
2 Load packages
Code
# knitr is require for creating html/pdf/word reports# formatR is used for soft-wrapping codeif (!"sketchy"%in%installed.packages()[,1]) remotes::install_github("maRce10/sketchy")# unload R packages (specific packages required for this code)x <-c("ggplot2","kableExtra","knitr","formatR","rprojroot","xaringanExtra","viridis","brms","ape","brmsish","corrplot","phytools","rstan",github ="maRce10/brmsish" )# install/ load packagessketchy::load_packages(packages = x)## set function to prune treesprep_tree <-function(tree, spp) { spp <-unique(spp)if (is(tree, "multiPhylo")) trees <-lapply(tree, function(x)drop.tip(phy = x, tip =setdiff(x$tip.label, spp)))else trees <-drop.tip(phy = tree, tip =setdiff(tree$tip.label, spp))return(tree)}rstan_options(auto_write =TRUE)
Code
## Open dataframes# read datatrees_owl <-read.nexus("./data/raw/BirdTree_Owl_Output.nex")consensus_tree_owl <-read.nexus("./data/raw/Owl_Consensus_Tree.nex")set.seed(123)trees_owl <- trees_owl[sample(1:100, size =40)]corr_df <- df <-readRDS("./data/raw/Owl_Duet.RDS")# Set categorical response variable as ordered factors (ordinal data) and #USE FOR BRMSdf$tip.labels <-as.factor(df$tip.labels) # binary categorical response variabledf$Duetting <-as.factor(df$Duetting) # categorical explanatory variabledf$Social_Bond <-as.factor(df$Social_Bond) # categorical explanatory variabledf$Territoriality <-as.factor(df$Territoriality) # categorical explanatory variabledf$White_Plumage <-as.factor(df$White_Plumage) # categorical explanatory variabledf$Nocturnality <-as.factor(df$Nocturnality) # categorical explanatory variabledf$Habitat_Density <-as.factor(df$Habitat_Density) # categorical explanatory variabledf$Migration <-as.factor(df$Migration) # categorical explanatory variable# scale and center numerical datadf$Central_Latitude <-scale(df$Central_Latitude, center =TRUE, scale =TRUE)# use if you need to reset rownames as sequential numbersrownames(df) <-1:nrow(df)# look at structurestr(df)
####################### Response variables ######################## Make the correlation table### NOTE: DEFAULT CODE DOES NOT REMOVE MISSING DATA; use complete.obs to drop nas.corrtab <-cor(corr_df[,-1], method ="pearson", use ="complete.obs")round(corrtab, 2)
# Set categorical data to analyze as numbersdf$duet <-as.numeric(df$Duetting)### phylogenetic signal for response variabletrait_duet <- df$duetlength(trait_duet)
Phylogenetic signal lambda : 0.251294
logL(lambda) : -37.722
LR(lambda=0) : 1.00417
P-value (based on LR test) : 0.316303
4 Statistical analysis
5 Taking into account phylogenetic uncertainty
5.1 Full model
Code
### See https://urldefense.proofpoint.com/v2/url?u=https-3A__psyarxiv.com_x8swp_&d=DwIGAg&c=t1KneP5CA95qj21Jnj2QJw&r=uXrXEa22P1XTtZOkZJzsx8pAQCDanQ2sMUk_AfMLQ0I&m=Th_rFO1G4mV3f039Te1VuvpmcjwF2KXjHAfcU0UhAb8vpbbU-nEL3HwCTlICHqS3&s=qolX0qBhJIjMDpanzBhiCR3QCeDrzGH4A9eyiqlhW2g&e= for explanation of types of ordinal models implemented in brms.# And https://urldefense.proofpoint.com/v2/url?u=https-3A__solomonkurz.netlify.app_post_2021-2D12-2D29-2Dnotes-2Don-2Dthe-2Dbayesian-2Dcumulative-2Dprobit_&d=DwIGAg&c=t1KneP5CA95qj21Jnj2QJw&r=uXrXEa22P1XTtZOkZJzsx8pAQCDanQ2sMUk_AfMLQ0I&m=Th_rFO1G4mV3f039Te1VuvpmcjwF2KXjHAfcU0UhAb8vpbbU-nEL3HwCTlICHqS3&s=PQ-Sgi8kE3P2Yamj_rtG-r2rZUbEB5iytYjn9NLil08&e= # set trees#A <- vcv.phylo(trees)# set parametersset.seed(123)parallel <-7# set this to the number of cores you want to use in the clusterthin <-100priors <-c(prior(normal(0, 2), class ="b"))chains <-4## run model### Owl duets: present/absent vs explanatory variablesmod <-phylogenetic_uncertainty(formula = Duetting ~ Social_Bond + Territoriality + Nocturnality + Habitat_Density + Migration + Central_Latitude + White_Plumage,data = df,phylos =prep_tree(trees_owl, spp = df$tip.labels),family =bernoulli(link ="logit"),chains = chains,cores = chains,iter =20000,prior = priors,control =list(adapt_delta =0.99, max_treedepth =15),init =0,thin = thin,sp.id.column ="tip.labels" )saveRDS(mod, "./data/processed/phylogenetic_uncertainty_model.RDS")
### See https://urldefense.proofpoint.com/v2/url?u=https-3A__psyarxiv.com_x8swp_&d=DwIGAg&c=t1KneP5CA95qj21Jnj2QJw&r=uXrXEa22P1XTtZOkZJzsx8pAQCDanQ2sMUk_AfMLQ0I&m=Th_rFO1G4mV3f039Te1VuvpmcjwF2KXjHAfcU0UhAb8vpbbU-nEL3HwCTlICHqS3&s=qolX0qBhJIjMDpanzBhiCR3QCeDrzGH4A9eyiqlhW2g&e= for explanation of types of ordinal models implemented in brms.# And https://urldefense.proofpoint.com/v2/url?u=https-3A__solomonkurz.netlify.app_post_2021-2D12-2D29-2Dnotes-2Don-2Dthe-2Dbayesian-2Dcumulative-2Dprobit_&d=DwIGAg&c=t1KneP5CA95qj21Jnj2QJw&r=uXrXEa22P1XTtZOkZJzsx8pAQCDanQ2sMUk_AfMLQ0I&m=Th_rFO1G4mV3f039Te1VuvpmcjwF2KXjHAfcU0UhAb8vpbbU-nEL3HwCTlICHqS3&s=PQ-Sgi8kE3P2Yamj_rtG-r2rZUbEB5iytYjn9NLil08&e= # set trees#A <- vcv.phylo(trees)# set parametersset.seed(123)parallel <-7# set this to the number of cores you want to use in the clusterthin <-1priors <-c(prior(normal(0, 2), class ="b"))chains <-4A <- ape::vcv.phylo(consensus_tree_owl)df$phylo <- df$tip.label## run modelmodel_simple <-brm( Duetting ~ Social_Bond + Territoriality + Nocturnality + Habitat_Density + Migration + Central_Latitude + White_Plumage + (1|gr(phylo, cov = A)),data = df,family =bernoulli(link ="logit"),chains = chains,cores = chains,iter =20000,prior = priors,control =list(adapt_delta =0.99, max_treedepth =15),init =0,thin = thin,data2 =list(A = A),)saveRDS(model_simple, "./data/processed/consensus_tree_model.RDS")