####################################################### # This is an introductory example script for the # R package "BioGeoBEARS" by Nick Matzke # # All scripts are copyright Nicholas J. Matzke, # please cite if you use. License: GPL-3 # http://cran.r-project.org/web/licenses/GPL-3 # # I am happy to answer questions at matzke@nimbios.org, but # I am more happy to answer questions on the # BioGeoBEARS google group # # The package is designed for ML and Bayesian inference # of # # (a) ancestral geographic ranges, and # # (b) perhaps more importantly, models for the # evolution of geographic range across a phylogeny. # # The example below implements and compares: # # (1) The standard 2-parameter DEC model implemented in # the program LAGRANGE (Ree & Smith 2008); users will # notice that the ML parameter inference and log- # likelihoods are identical # # (2) A DEC+J model implemented in BioGeoBEARS, wherein # a third parameter, j, is added, representing the # relative per-event weight of founder-event / jump # speciation events at cladogenesis events. The # higher j is, the more probability these events have, # and the less probability the standard LAGRANGE # cladogenesis events have. # # (3) Some standard model-testing (LRT and AIC) is # implemented at the end so that users may compare models # # (4) The script does similar tests of a DIVA-like model (Ronquist 1997) # and a BAYAREA-like model (Landis, Matzke, Moore, & Huelsenbeck, 2013) # ####################################################### ####################################################### # Installing BioGeoBEARS ####################################################### # Uncomment this command to get everything # Please use the "0-cloud" R repository at "http://cran.rstudio.com" as it is # the only one that keeps download statistics ####################################################### # # # # Install BioGeoBEARS from CRAN 0-cloud: #install.packages("BioGeoBEARS", dependencies=TRUE, repos="http://cran.rstudio.com") # ####################################################### ####################################################### # SETUP -- libraries/BioGeoBEARS updates ####################################################### # Load the package (after installation, see above). library(GenSA) # GenSA is better than optimx (although somewhat slower) library(FD) # for FD::maxent() (make sure this is up-to-date) library(snow) # (if you want to use multicore functionality; some systems/R versions prefer library(parallel), try either) library(parallel) ####################################################### # 2018-10-10 update: I have been putting the # updates on CRAN/GitHub # You should use: # rexpokit version 0.26.6 from CRAN # cladoRcpp version 0.15 from CRAN # BioGeoBEARS version 1.1 from GitHub, install with: library(devtools) devtools::install_github(repo="nmatzke/BioGeoBEARS") #If the rlang error happens again, run this and then reinstall BioGeoBEARS #remove.packages("rlang") #install.packages("rlang") ####################################################### library(rexpokit) library(cladoRcpp) library(BioGeoBEARS) ####################################################### # CUT: The old instructions to source() online upgrade .R files have been deleted, # all updates are now on the GitHub version of the package, version 1.1+ ####################################################### ####################################################### # (This local-sourcing is mostly useful for Nick, while actively developing) # Local source()-ing method -- uses BioGeoBEARS sourceall() function # on a directory of .R files, so you don't have to type them out. # The directories here are on my machine, you would have to make a # directory, save the .R files there, and refer to them. # # NOTE: it's best to source the "cladoRcpp.R" update first, to avoid warnings like this: ## ## Note: possible error in 'rcpp_calc_anclikes_sp_COOweights_faster(Rcpp_leftprobs = tmpca_1, ': ## unused arguments (m = m, m_null_range = include_null_range, jts_matrix = jts_matrix) ## # # TO USE: Delete or comment out the 'source("http://...")' commands above, and un-comment # the below... ######################################################################## # Un-comment (and fix directory paths) to use: #library(BioGeoBEARS) #source("/drives/Dropbox/_njm/__packages/cladoRcpp_setup/cladoRcpp.R") #sourceall("/drives/Dropbox/_njm/__packages/BioGeoBEARS_setup/") #calc_loglike_sp = compiler::cmpfun(calc_loglike_sp_prebyte) # crucial to fix bug in uppass calculations #calc_independent_likelihoods_on_each_branch = compiler::cmpfun(calc_independent_likelihoods_on_each_branch_prebyte) ######################################################################## ####################################################### # SETUP: YOUR WORKING DIRECTORY ####################################################### # You will need to set your working directory to match your local system # Note these very handy functions! # Command "setwd(x)" sets your working directory # Command "getwd()" gets your working directory and tells you what it is. # Command "list.files()" lists the files in your working directory # To get help on any command, use "?". E.g., "?list.files" # Set your working directory for output files # default here is your home directory ("~") # Change this as you like getwd() wd = normalizePath("/Users/IVWil/OneDrive/Desktop/Wilenzik_2022/R_script") setwd(wd) # Double-check your working directory with getwd() getwd() ####################################################### # SETUP: Extension data directory ####################################################### # When R packages contain extra files, they are stored in the "extdata" directory # inside the installed package. # # BioGeoBEARS contains various example files and scripts in its extdata directory. # # Each computer operating system might install BioGeoBEARS in a different place, # depending on your OS and settings. # # However, you can find the extdata directory like this: extdata_dir = normalizePath(system.file("extdata", package="BioGeoBEARS")) extdata_dir list.files(extdata_dir) # "system.file" looks in the directory of a specified package (in this case BioGeoBEARS) # The function "np" is just a shortcut for normalizePath(), which converts the # path to the format appropriate for your system (e.g., Mac/Linux use "/", but # Windows uses "\\", if memory serves). # Note from Ian -> np() doesnt work; have to write out normalizePath() # Even when using your own data files, you should KEEP these commands in your # script, since the plot_BioGeoBEARS_results function needs a script from the # extdata directory to calculate the positions of "corners" on the plot. This cannot # be made into a straight up BioGeoBEARS function because it uses C routines # from the package APE which do not pass R CMD check for some reason. ####################################################### # SETUP: YOUR TREE FILE AND GEOGRAPHY FILE ####################################################### # Example files are given below. To run your own data, # make the below lines point to your own files, e.g. # trfn = "/mydata/frogs/frogBGB/tree.newick" # geogfn = "/mydata/frogs/frogBGB/geog.data" ####################################################### # Phylogeny file # Notes: # 1. Must be binary/bifurcating: no polytomies # 2. No negative branchlengths (e.g. BEAST MCC consensus trees sometimes have negative branchlengths) # 3. Be careful of very short branches, as BioGeoBEARS will interpret ultrashort branches as direct ancestors # 4. You can use non-ultrametric trees, but BioGeoBEARS will interpret any tips significantly below the # top of the tree as fossils! This is only a good idea if you actually do have fossils in your tree, # as in e.g. Wood, Matzke et al. (2013), Systematic Biology. # 5. The default settings of BioGeoBEARS make sense for trees where the branchlengths are in units of # millions of years, and the tree is 1-1000 units tall. If you have a tree with a total height of # e.g. 0.00001, you will need to adjust e.g. the max values of d and e, or (simpler) multiply all # your branchlengths to get them into reasonable units. # 6. DON'T USE SPACES IN SPECIES NAMES, USE E.G. "_" ####################################################### # This is the example Newick file for Hawaiian Psychotria # (from Ree & Smith 2008) # "trfn" = "tree file name" #trfn = np(paste(addslash(extdata_dir), "Psychotria_5.2.newick", sep="")) trfn = normalizePath("squam_shl_new_Posterior_5415.1.ladder.tre") # Look at the raw Newick file: moref(trfn) # Look at your phylogeny (plots to a PDF, which avoids issues with multiple graphics in same window): pdffn = "squam_shl_new_Posterior_5415.1.ladder.tre.pdf" pdf(file=pdffn, width=12, height=198) tr = read.tree(trfn) tr plot(tr,cex=0.2,label.offset = 0.2) title("Squamata data-only phylogeny (5415 taxa) from Tonini et al. (2016)") axisPhylo() # plots timescale dev.off() cmdstr = paste0("open ", pdffn) system(cmdstr) ####################################################### # Geography file # Notes: # 1. This is a PHYLIP-formatted file. This means that in the # first line, # - the 1st number equals the number of rows (species) # - the 2nd number equals the number of columns (number of areas) # - after a tab, put the areas in parentheses, with spaces: (A B C D) # # 1.5. Example first line: # 10 4 (A B C D) # # 2. The second line, and subsequent lines: # speciesA 0110 # speciesB 0111 # speciesC 0001 # ... # # 2.5a. This means a TAB between the species name and the area 0/1s # 2.5b. This also means NO SPACE AND NO TAB between the area 0/1s. # # 3. See example files at: # http://phylo.wikidot.com/biogeobears#files # # 4. Make you understand what a PLAIN-TEXT EDITOR is: # http://phylo.wikidot.com/biogeobears#texteditors # # 3. The PHYLIP format is the same format used for C++ LAGRANGE geography files. # # 4. All names in the geography file must match names in the phylogeny file. # # 5. DON'T USE SPACES IN SPECIES NAMES, USE E.G. "_" # # 6. Operational taxonomic units (OTUs) should ideally be phylogenetic lineages, # i.e. genetically isolated populations. These may or may not be identical # with species. You would NOT want to just use specimens, as each specimen # automatically can only live in 1 area, which will typically favor DEC+J # models. This is fine if the species/lineages really do live in single areas, # but you wouldn't want to assume this without thinking about it at least. # In summary, you should collapse multiple specimens into species/lineages if # data indicates they are the same genetic population. ###################################################### # This is the example geography file for Hawaiian Psychotria # (from Ree & Smith 2008) geogfn = np("squam_9_areas_5415_taxa_11_January_2022_names.txt") # Look at the raw geography text file: moref(geogfn) # Look at your geographic range data: tipranges = getranges_from_LagrangePHYLIP(lgdata_fn=geogfn) tipranges # Maximum range size observed: max(rowSums(dfnums_to_numeric(tipranges@df))) # Set the maximum number of areas any species may occupy; this cannot be larger # than the number of areas you set up, but it can be smaller. max_range_size = 4 #################################################### #################################################### # KEY HINT: The number of states (= number of different possible geographic ranges) # depends on (a) the number of areas and (b) max_range_size. # If you have more than about 500-600 states, the calculations will get REALLY slow, # since the program has to exponentiate a matrix of e.g. 600x600. Often the computer # will just sit there and crunch, and never get through the calculation of the first # likelihood. # # (this is also what is usually happening when LAGRANGE hangs: you have too many states!) # # To check the number of states for a given number of ranges, try: numstates_from_numareas(numareas=4, maxareas=4, include_null_range=TRUE) numstates_from_numareas(numareas=4, maxareas=4, include_null_range=FALSE) numstates_from_numareas(numareas=4, maxareas=3, include_null_range=TRUE) numstates_from_numareas(numareas=4, maxareas=2, include_null_range=TRUE) # Large numbers of areas have problems: numstates_from_numareas(numareas=10, maxareas=10, include_null_range=TRUE) # ...unless you limit the max_range_size: numstates_from_numareas(numareas=10, maxareas=2, include_null_range=TRUE) #################################################### #################################################### ####################################################### ####################################################### # DEC AND DEC+J ANALYSIS ####################################################### ####################################################### # NOTE: The BioGeoBEARS "DEC" model is identical with # the Lagrange DEC model, and should return identical # ML estimates of parameters, and the same # log-likelihoods, for the same datasets. # # Ancestral state probabilities at nodes will be slightly # different, since BioGeoBEARS is reporting the # ancestral state probabilities under the global ML # model, and Lagrange is reporting ancestral state # probabilities after re-optimizing the likelihood # after fixing the state at each node. These will # be similar, but not identical. See Matzke (2014), # Systematic Biology, for discussion. # # Also see Matzke (2014) for presentation of the # DEC+J model. ####################################################### ####################################################### ####################################################### ####################################################### ####################################################### # Run DEC ####################################################### # Get your states list (assuming, say, 4-area analysis, with max. rangesize=4) #install.packages("cladoRcpp") #library("cladoRcpp") #max_range_size = 4 #areas = getareas_from_tipranges_object(tipranges) #areas = c("A", "B", "C", "D", "E", "F", "G", "H", "I") # This is the list of states/ranges, where each state/range # is a list of areas, counting from 0 #states_list_0based = rcpp_areas_list_to_states_list(areas=areas, maxareas=max_range_size, include_null_range=TRUE) # Make the list of ranges #ranges_list = NULL #for (i in 1:length(states_list_0based)) #{ # if ( (length(states_list_0based[[i]]) == 1) && (is.na(states_list_0based[[i]])) ) # { # tmprange = "_" # } else { # tmprange = paste(areas[states_list_0based[[i]]+1], collapse="") # } # ranges_list = c(ranges_list, tmprange) #} # Look at the ranges list #ranges_list # Intitialize a default model (DEC model) BioGeoBEARS_run_object = define_BioGeoBEARS_run() # Give BioGeoBEARS the location of the phylogeny Newick file BioGeoBEARS_run_object$trfn = trfn # Give BioGeoBEARS the location of the geography text file BioGeoBEARS_run_object$geogfn = geogfn # Input the maximum range size BioGeoBEARS_run_object$max_range_size = max_range_size BioGeoBEARS_run_object$min_branchlength = 0.000001 # Min to treat tip as a direct ancestor (no speciation event) BioGeoBEARS_run_object$include_null_range = TRUE # set to FALSE for e.g. DEC* model, DEC*+J, etc. # (For DEC* and other "*" models, please cite: Massana, Kathryn A.; Beaulieu, # Jeremy M.; Matzke, Nicholas J.; O’Meara, Brian C. (2015). Non-null Effects of # the Null Range in Biogeographic Models: Exploring Parameter Estimation in the # DEC Model. bioRxiv, http://biorxiv.org/content/early/2015/09/16/026914 ) # Also: search script on "include_null_range" for other places to change # Set up a time-stratified analysis: # 1. Here, un-comment ONLY the files you want to use. # 2. Also un-comment "BioGeoBEARS_run_object = section_the_tree(...", below. # 3. For example files see (a) extdata_dir, # or (b) http://phylo.wikidot.com/biogeobears#files # and BioGeoBEARS Google Group posts for further hints) # # Uncomment files you wish to use in time-stratified analyses: #BioGeoBEARS_run_object$timesfn = "timeperiods.txt" #BioGeoBEARS_run_object$dispersal_multipliers_fn = "manual_dispersal_multipliers.txt" #BioGeoBEARS_run_object$areas_allowed_fn = "areas_allowed.txt" #BioGeoBEARS_run_object$areas_adjacency_fn = "areas_adjacency.txt" #BioGeoBEARS_run_object$distsfn = "distances_matrix.txt" # See notes on the distances model on PhyloWiki's BioGeoBEARS updates page. # Speed options and multicore processing if desired BioGeoBEARS_run_object$on_NaN_error = -1e50 # returns very low lnL if parameters produce NaN error (underflow check) BioGeoBEARS_run_object$speedup = TRUE # shorcuts to speed ML search; use FALSE if worried (e.g. >3 params) BioGeoBEARS_run_object$use_optimx = "GenSA" # if FALSE, use optim() instead of optimx() BioGeoBEARS_run_object$num_cores_to_use = 4 #I believe my computer has four cores # (use more cores to speed it up; this requires # library(parallel) and/or library(snow). The package "parallel" # is now default on Macs in R 3.0+, but apparently still # has to be typed on some Windows machines. Note: apparently # parallel works on Mac command-line R, but not R.app. # BioGeoBEARS checks for this and resets to 1 # core with R.app) ##FOSSIL CONSTRAINTS #BioGeoBEARS_run_object$fixnodes = c(5422,7005,8781) #BioGeoBEARS_run_object$fixlikes = rbind( c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,1,1,0,1,0), #c(0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0), #c(0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0)) BioGeoBEARS_run_object$fixnodes = c(7005,8249,8299,8781) BioGeoBEARS_run_object$fixlikes = rbind( c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,1,1,0,1,0), c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,1,1,0,1,0), c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,1,1,0,1,0), c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,1,1,0,1,0)) # Sparse matrix exponentiation is an option for huge numbers of ranges/states (600+) # I have experimented with sparse matrix exponentiation in EXPOKIT/rexpokit, # but the results are imprecise and so I haven't explored it further. # In a Bayesian analysis, it might work OK, but the ML point estimates are # not identical. # Also, I have not implemented all functions to work with force_sparse=TRUE. # Volunteers are welcome to work on it!! BioGeoBEARS_run_object$force_sparse = FALSE # force_sparse=TRUE causes pathology & isn't much faster at this scale # This function loads the dispersal multiplier matrix etc. from the text files into the model object. Required for these to work! # (It also runs some checks on these inputs for certain errors.) BioGeoBEARS_run_object = readfiles_BioGeoBEARS_run(BioGeoBEARS_run_object) # Divide the tree up by timeperiods/strata (uncomment this for stratified analysis) #BioGeoBEARS_run_object = section_the_tree(inputs=BioGeoBEARS_run_object, make_master_table=TRUE, plot_pieces=FALSE) # The stratified tree is described in this table: #BioGeoBEARS_run_object$master_table # Good default settings to get ancestral states BioGeoBEARS_run_object$return_condlikes_table = TRUE BioGeoBEARS_run_object$calc_TTL_loglike_from_condlikes_table = TRUE BioGeoBEARS_run_object$calc_ancprobs = TRUE # get ancestral states from optim run # Set up DEC model # (nothing to do; defaults) # Look at the BioGeoBEARS_run_object; it's just a list of settings etc. BioGeoBEARS_run_object # This contains the model object BioGeoBEARS_run_object$BioGeoBEARS_model_object # This table contains the parameters of the model BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table # Run this to check inputs. Read the error messages if you get them! check_BioGeoBEARS_run(BioGeoBEARS_run_object) # For a slow analysis, run once, then set runslow=FALSE to just # load the saved result. runslow = TRUE resfn = "Squamata_DEC_M0_unconstrained_v2.Rdata" if (runslow) { res = bears_optim_run(BioGeoBEARS_run_object) res save(res, file=resfn) resDEC = res } else { # Loads to "res" load(resfn) resDEC = res } ####################################################### # Run DEC+J ####################################################### BioGeoBEARS_run_object = define_BioGeoBEARS_run() BioGeoBEARS_run_object$trfn = trfn BioGeoBEARS_run_object$geogfn = geogfn BioGeoBEARS_run_object$max_range_size = max_range_size BioGeoBEARS_run_object$min_branchlength = 0.000001 # Min to treat tip as a direct ancestor (no speciation event) BioGeoBEARS_run_object$include_null_range = TRUE # set to FALSE for e.g. DEC* model, DEC*+J, etc. # (For DEC* and other "*" models, please cite: Massana, Kathryn A.; Beaulieu, # Jeremy M.; Matzke, Nicholas J.; O’Meara, Brian C. (2015). Non-null Effects of # the Null Range in Biogeographic Models: Exploring Parameter Estimation in the # DEC Model. bioRxiv, http://biorxiv.org/content/early/2015/09/16/026914 ) # Also: search script on "include_null_range" for other places to change # Set up a time-stratified analysis: #BioGeoBEARS_run_object$timesfn = "timeperiods.txt" #BioGeoBEARS_run_object$dispersal_multipliers_fn = "manual_dispersal_multipliers.txt" #BioGeoBEARS_run_object$areas_allowed_fn = "areas_allowed.txt" #BioGeoBEARS_run_object$areas_adjacency_fn = "areas_adjacency.txt" #BioGeoBEARS_run_object$distsfn = "distances_matrix.txt" # See notes on the distances model on PhyloWiki's BioGeoBEARS updates page. # Speed options and multicore processing if desired BioGeoBEARS_run_object$on_NaN_error = -1e50 # returns very low lnL if parameters produce NaN error (underflow check) BioGeoBEARS_run_object$speedup = TRUE # shorcuts to speed ML search; use FALSE if worried (e.g. >3 params) BioGeoBEARS_run_object$use_optimx = "GenSA" # if FALSE, use optim() instead of optimx() BioGeoBEARS_run_object$num_cores_to_use = 1 BioGeoBEARS_run_object$force_sparse = FALSE # force_sparse=TRUE causes pathology & isn't much faster at this scale # This function loads the dispersal multiplier matrix etc. from the text files into the model object. Required for these to work! # (It also runs some checks on these inputs for certain errors.) BioGeoBEARS_run_object = readfiles_BioGeoBEARS_run(BioGeoBEARS_run_object) # Divide the tree up by timeperiods/strata (uncomment this for stratified analysis) #BioGeoBEARS_run_object = section_the_tree(inputs=BioGeoBEARS_run_object, make_master_table=TRUE, plot_pieces=FALSE) # The stratified tree is described in this table: #BioGeoBEARS_run_object$master_table # Good default settings to get ancestral states BioGeoBEARS_run_object$return_condlikes_table = TRUE BioGeoBEARS_run_object$calc_TTL_loglike_from_condlikes_table = TRUE BioGeoBEARS_run_object$calc_ancprobs = TRUE # get ancestral states from optim run # Set up DEC+J model # Get the ML parameter values from the 2-parameter nested model # (this will ensure that the 3-parameter model always does at least as good) dstart = resDEC$outputs@params_table["d","est"] estart = resDEC$outputs@params_table["e","est"] jstart = 0.0001 # Input starting values for d, e BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["d","init"] = dstart BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["d","est"] = dstart BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["e","init"] = estart BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["e","est"] = estart # Add j as a free parameter BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["j","type"] = "free" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["j","init"] = jstart BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["j","est"] = jstart check_BioGeoBEARS_run(BioGeoBEARS_run_object) resfn = "Squamata_DEC+J_M0_unconstrained_v1.Rdata" runslow = TRUE if (runslow) { #sourceall("/Dropbox/_njm/__packages/BioGeoBEARS_setup/") res = bears_optim_run(BioGeoBEARS_run_object) res save(res, file=resfn) resDECj = res } else { # Loads to "res" load(resfn) resDECj = res } ####################################################### # PDF plots ####################################################### pdffn = "Squamata_DEC_vs_DEC+J_M0_unconstrained_v1.pdf" pdf(pdffn, width=12, height=198) ####################################################### # Plot ancestral states - DEC ####################################################### analysis_titletxt ="BioGeoBEARS DEC on Squamata M0_unconstrained" # Setup results_object = resDEC scriptdir = np(system.file("extdata/a_scripts", package="BioGeoBEARS")) # States res2 = plot_BioGeoBEARS_results(results_object, analysis_titletxt, addl_params=list("j"), plotwhat="text", label.offset=0.45, tipcex=0.3, statecex=0.3, splitcex=0.2, titlecex=0.8, plotsplits=TRUE, cornercoords_loc=scriptdir, include_null_range=TRUE, tr=tr, tipranges=tipranges) # Pie chart plot_BioGeoBEARS_results(results_object, analysis_titletxt, addl_params=list("j"), plotwhat="pie", label.offset=0.45, tipcex=0.3, statecex=0.3, splitcex=0.2, titlecex=0.8, plotsplits=TRUE, cornercoords_loc=scriptdir, include_null_range=TRUE, tr=tr, tipranges=tipranges) ####################################################### # Plot ancestral states - DECJ ####################################################### analysis_titletxt ="BioGeoBEARS DEC+J on Squamata M0_unconstrained" # Setup results_object = resDECj scriptdir = np(system.file("extdata/a_scripts", package="BioGeoBEARS")) # States res1 = plot_BioGeoBEARS_results(results_object, analysis_titletxt, addl_params=list("j"), plotwhat="text", label.offset=0.45, tipcex=0.3, statecex=0.3, splitcex=0.2, titlecex=0.8, plotsplits=TRUE, cornercoords_loc=scriptdir, include_null_range=TRUE, tr=tr, tipranges=tipranges) # Pie chart plot_BioGeoBEARS_results(results_object, analysis_titletxt, addl_params=list("j"), plotwhat="pie", label.offset=0.45, tipcex=0.3, statecex=0.3, splitcex=0.2, titlecex=0.8, plotsplits=TRUE, cornercoords_loc=scriptdir, include_null_range=TRUE, tr=tr, tipranges=tipranges) dev.off() # Turn off PDF cmdstr = paste("open ", pdffn, sep="") system(cmdstr) # Plot it ####################################################### ####################################################### # DIVALIKE AND DIVALIKE+J ANALYSIS ####################################################### ####################################################### # NOTE: The BioGeoBEARS "DIVALIKE" model is not identical with # Ronquist (1997)'s parsimony DIVA. It is a likelihood # interpretation of DIVA, constructed by modelling DIVA's # processes the way DEC does, but only allowing the # processes DIVA allows (widespread vicariance: yes; subset # sympatry: no; see Ronquist & Sanmartin 2011, Figure 4). # # DIVALIKE is a likelihood interpretation of parsimony # DIVA, and it is "like DIVA" -- similar to, but not # identical to, parsimony DIVA. # # I thus now call the model "DIVALIKE", and you should also. ;-) ####################################################### ####################################################### ####################################################### # Run DIVALIKE ####################################################### BioGeoBEARS_run_object = define_BioGeoBEARS_run() BioGeoBEARS_run_object$trfn = trfn BioGeoBEARS_run_object$geogfn = geogfn BioGeoBEARS_run_object$max_range_size = max_range_size BioGeoBEARS_run_object$min_branchlength = 0.000001 # Min to treat tip as a direct ancestor (no speciation event) BioGeoBEARS_run_object$include_null_range = TRUE # set to FALSE for e.g. DEC* model, DEC*+J, etc. # (For DEC* and other "*" models, please cite: Massana, Kathryn A.; Beaulieu, # Jeremy M.; Matzke, Nicholas J.; O’Meara, Brian C. (2015). Non-null Effects of # the Null Range in Biogeographic Models: Exploring Parameter Estimation in the # DEC Model. bioRxiv, http://biorxiv.org/content/early/2015/09/16/026914 ) # Also: search script on "include_null_range" for other places to change # Set up a time-stratified analysis: #BioGeoBEARS_run_object$timesfn = "timeperiods.txt" #BioGeoBEARS_run_object$dispersal_multipliers_fn = "manual_dispersal_multipliers.txt" #BioGeoBEARS_run_object$areas_allowed_fn = "areas_allowed.txt" #BioGeoBEARS_run_object$areas_adjacency_fn = "areas_adjacency.txt" #BioGeoBEARS_run_object$distsfn = "distances_matrix.txt" # See notes on the distances model on PhyloWiki's BioGeoBEARS updates page. # Speed options and multicore processing if desired BioGeoBEARS_run_object$on_NaN_error = -1e50 # returns very low lnL if parameters produce NaN error (underflow check) BioGeoBEARS_run_object$speedup = TRUE # shorcuts to speed ML search; use FALSE if worried (e.g. >3 params) BioGeoBEARS_run_object$use_optimx = "GenSA" # if FALSE, use optim() instead of optimx() BioGeoBEARS_run_object$num_cores_to_use = 1 BioGeoBEARS_run_object$force_sparse = FALSE # force_sparse=TRUE causes pathology & isn't much faster at this scale # This function loads the dispersal multiplier matrix etc. from the text files into the model object. Required for these to work! # (It also runs some checks on these inputs for certain errors.) BioGeoBEARS_run_object = readfiles_BioGeoBEARS_run(BioGeoBEARS_run_object) # Divide the tree up by timeperiods/strata (uncomment this for stratified analysis) #BioGeoBEARS_run_object = section_the_tree(inputs=BioGeoBEARS_run_object, make_master_table=TRUE, plot_pieces=FALSE) # The stratified tree is described in this table: #BioGeoBEARS_run_object$master_table # Good default settings to get ancestral states BioGeoBEARS_run_object$return_condlikes_table = TRUE BioGeoBEARS_run_object$calc_TTL_loglike_from_condlikes_table = TRUE BioGeoBEARS_run_object$calc_ancprobs = TRUE # get ancestral states from optim run # Set up DIVALIKE model # Remove subset-sympatry BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["s","type"] = "fixed" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["s","init"] = 0.0 BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["s","est"] = 0.0 BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["ysv","type"] = "2-j" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["ys","type"] = "ysv*1/2" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["y","type"] = "ysv*1/2" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["v","type"] = "ysv*1/2" # Allow classic, widespread vicariance; all events equiprobable BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["mx01v","type"] = "fixed" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["mx01v","init"] = 0.5 BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["mx01v","est"] = 0.5 # No jump dispersal/founder-event speciation # BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["j","type"] = "free" # BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["j","init"] = 0.01 # BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["j","est"] = 0.01 check_BioGeoBEARS_run(BioGeoBEARS_run_object) runslow = TRUE resfn = "Squamata_DIVALIKE_M0_unconstrained_v1.Rdata" if (runslow) { res = bears_optim_run(BioGeoBEARS_run_object) res save(res, file=resfn) resDIVALIKE = res } else { # Loads to "res" load(resfn) resDIVALIKE = res } ####################################################### # Run DIVALIKE+J ####################################################### BioGeoBEARS_run_object = define_BioGeoBEARS_run() BioGeoBEARS_run_object$trfn = trfn BioGeoBEARS_run_object$geogfn = geogfn BioGeoBEARS_run_object$max_range_size = max_range_size BioGeoBEARS_run_object$min_branchlength = 0.000001 # Min to treat tip as a direct ancestor (no speciation event) BioGeoBEARS_run_object$include_null_range = TRUE # set to FALSE for e.g. DEC* model, DEC*+J, etc. # (For DEC* and other "*" models, please cite: Massana, Kathryn A.; Beaulieu, # Jeremy M.; Matzke, Nicholas J.; O’Meara, Brian C. (2015). Non-null Effects of # the Null Range in Biogeographic Models: Exploring Parameter Estimation in the # DEC Model. bioRxiv, http://biorxiv.org/content/early/2015/09/16/026914 ) # Also: search script on "include_null_range" for other places to change # Set up a time-stratified analysis: #BioGeoBEARS_run_object$timesfn = "timeperiods.txt" #BioGeoBEARS_run_object$dispersal_multipliers_fn = "manual_dispersal_multipliers.txt" #BioGeoBEARS_run_object$areas_allowed_fn = "areas_allowed.txt" #BioGeoBEARS_run_object$areas_adjacency_fn = "areas_adjacency.txt" #BioGeoBEARS_run_object$distsfn = "distances_matrix.txt" # See notes on the distances model on PhyloWiki's BioGeoBEARS updates page. # Speed options and multicore processing if desired BioGeoBEARS_run_object$on_NaN_error = -1e50 # returns very low lnL if parameters produce NaN error (underflow check) BioGeoBEARS_run_object$speedup = TRUE # shorcuts to speed ML search; use FALSE if worried (e.g. >3 params) BioGeoBEARS_run_object$use_optimx = "GenSA" # if FALSE, use optim() instead of optimx() BioGeoBEARS_run_object$num_cores_to_use = 8 BioGeoBEARS_run_object$force_sparse = FALSE # force_sparse=TRUE causes pathology & isn't much faster at this scale # This function loads the dispersal multiplier matrix etc. from the text files into the model object. Required for these to work! # (It also runs some checks on these inputs for certain errors.) BioGeoBEARS_run_object = readfiles_BioGeoBEARS_run(BioGeoBEARS_run_object) # Divide the tree up by timeperiods/strata (uncomment this for stratified analysis) #BioGeoBEARS_run_object = section_the_tree(inputs=BioGeoBEARS_run_object, make_master_table=TRUE, plot_pieces=FALSE) # The stratified tree is described in this table: #BioGeoBEARS_run_object$master_table # Good default settings to get ancestral states BioGeoBEARS_run_object$return_condlikes_table = TRUE BioGeoBEARS_run_object$calc_TTL_loglike_from_condlikes_table = TRUE BioGeoBEARS_run_object$calc_ancprobs = TRUE # get ancestral states from optim run # Set up DIVALIKE+J model # Get the ML parameter values from the 2-parameter nested model # (this will ensure that the 3-parameter model always does at least as good) dstart = resDIVALIKE$outputs@params_table["d","est"] estart = resDIVALIKE$outputs@params_table["e","est"] jstart = 0.0001 # Input starting values for d, e BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["d","init"] = dstart BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["d","est"] = dstart BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["e","init"] = estart BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["e","est"] = estart # Remove subset-sympatry BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["s","type"] = "fixed" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["s","init"] = 0.0 BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["s","est"] = 0.0 BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["ysv","type"] = "2-j" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["ys","type"] = "ysv*1/2" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["y","type"] = "ysv*1/2" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["v","type"] = "ysv*1/2" # Allow classic, widespread vicariance; all events equiprobable BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["mx01v","type"] = "fixed" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["mx01v","init"] = 0.5 BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["mx01v","est"] = 0.5 # Add jump dispersal/founder-event speciation BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["j","type"] = "free" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["j","init"] = jstart BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["j","est"] = jstart # Under DIVALIKE+J, the max of "j" should be 2, not 3 (as is default in DEC+J) BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["j","min"] = 0.00001 BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["j","max"] = 1.99999 check_BioGeoBEARS_run(BioGeoBEARS_run_object) resfn = "Squamata_DIVALIKE+J_M0_unconstrained_v1.Rdata" runslow = TRUE if (runslow) { #sourceall("/Dropbox/_njm/__packages/BioGeoBEARS_setup/") res = bears_optim_run(BioGeoBEARS_run_object) res save(res, file=resfn) resDIVALIKEj = res } else { # Loads to "res" load(resfn) resDIVALIKEj = res } pdffn = "Squamata_DIVALIKE_vs_DIVALIKE+J_M0_unconstrained_v1.pdf" pdf(pdffn, width=12, height=198) ####################################################### # Plot ancestral states - DIVALIKE ####################################################### analysis_titletxt ="BioGeoBEARS DIVALIKE on Squamata M0_unconstrained" # Setup results_object = resDIVALIKE scriptdir = np(system.file("extdata/a_scripts", package="BioGeoBEARS")) # States res2 = plot_BioGeoBEARS_results(results_object, analysis_titletxt, addl_params=list("j"), plotwhat="text", label.offset=0.45, tipcex=0.3, statecex=0.3, splitcex=0.2, titlecex=0.8, plotsplits=TRUE, cornercoords_loc=scriptdir, include_null_range=TRUE, tr=tr, tipranges=tipranges) # Pie chart plot_BioGeoBEARS_results(results_object, analysis_titletxt, addl_params=list("j"), plotwhat="pie", label.offset=0.45, tipcex=0.3, statecex=0.3, splitcex=0.2, titlecex=0.8, plotsplits=TRUE, cornercoords_loc=scriptdir, include_null_range=TRUE, tr=tr, tipranges=tipranges) ####################################################### # Plot ancestral states - DIVALIKE+J ####################################################### analysis_titletxt ="BioGeoBEARS DIVALIKE+J on Squamata M0_unconstrained" # Setup results_object = resDIVALIKEj scriptdir = np(system.file("extdata/a_scripts", package="BioGeoBEARS")) # States res1 = plot_BioGeoBEARS_results(results_object, analysis_titletxt, addl_params=list("j"), plotwhat="text", label.offset=0.45, tipcex=0.3, statecex=0.3, splitcex=0.2, titlecex=0.8, plotsplits=TRUE, cornercoords_loc=scriptdir, include_null_range=TRUE, tr=tr, tipranges=tipranges) # Pie chart plot_BioGeoBEARS_results(results_object, analysis_titletxt, addl_params=list("j"), plotwhat="pie", label.offset=0.45, tipcex=0.3, statecex=0.3, splitcex=0.2, titlecex=0.8, plotsplits=TRUE, cornercoords_loc=scriptdir, include_null_range=TRUE, tr=tr, tipranges=tipranges) dev.off() cmdstr = paste("open ", pdffn, sep="") system(cmdstr) ####################################################### ####################################################### # BAYAREALIKE AND BAYAREALIKE+J ANALYSIS ####################################################### ####################################################### # NOTE: As with DIVA, the BioGeoBEARS BayArea-like model is # not identical with the full Bayesian model implemented # in the "BayArea" program of Landis et al. (2013). # # Instead, this is a simplified likelihood interpretation # of the model. Basically, in BayArea and BioGeoBEARS-BAYAREALIKE, # "d" and "e" work like they do in the DEC model of Lagrange # (and BioGeoBEARS), and then BayArea's cladogenesis assumption # (which is that nothing in particular happens at cladogenesis) is # replicated by BioGeoBEARS. # # This leaves out 3 important things that are in BayArea: # 1. Distance dependence (you can add this with a distances # matrix + the "x" parameter in BioGeoBEARS, however) # 2. A correction for disallowing "e" events that drive # a species extinct (a null geographic range) # 3. The neat Bayesian sampling of histories, which allows # analyses on large numbers of areas. # # The main purpose of having a "BAYAREALIKE" model is # to test the importance of the cladogenesis model on # particular datasets. Does it help or hurt the data # likelihood if there is no special cladogenesis process? # # BAYAREALIKE is a likelihood interpretation of BayArea, # and it is "like BayArea" -- similar to, but not # identical to, Bayesian BayArea. # I thus now call the model "BAYAREALIKE", and you should also. ;-) ####################################################### ####################################################### ####################################################### # Run BAYAREALIKE ####################################################### BioGeoBEARS_run_object = define_BioGeoBEARS_run() BioGeoBEARS_run_object$trfn = trfn BioGeoBEARS_run_object$geogfn = geogfn BioGeoBEARS_run_object$max_range_size = max_range_size BioGeoBEARS_run_object$min_branchlength = 0.000001 # Min to treat tip as a direct ancestor (no speciation event) BioGeoBEARS_run_object$include_null_range = TRUE # set to FALSE for e.g. DEC* model, DEC*+J, etc. # (For DEC* and other "*" models, please cite: Massana, Kathryn A.; Beaulieu, # Jeremy M.; Matzke, Nicholas J.; O’Meara, Brian C. (2015). Non-null Effects of # the Null Range in Biogeographic Models: Exploring Parameter Estimation in the # DEC Model. bioRxiv, http://biorxiv.org/content/early/2015/09/16/026914 ) # Also: search script on "include_null_range" for other places to change # Set up a time-stratified analysis: #BioGeoBEARS_run_object$timesfn = "timeperiods.txt" #BioGeoBEARS_run_object$dispersal_multipliers_fn = "manual_dispersal_multipliers.txt" #BioGeoBEARS_run_object$areas_allowed_fn = "areas_allowed.txt" #BioGeoBEARS_run_object$areas_adjacency_fn = "areas_adjacency.txt" #BioGeoBEARS_run_object$distsfn = "distances_matrix.txt" # See notes on the distances model on PhyloWiki's BioGeoBEARS updates page. # Speed options and multicore processing if desired BioGeoBEARS_run_object$on_NaN_error = -1e50 # returns very low lnL if parameters produce NaN error (underflow check) BioGeoBEARS_run_object$speedup = TRUE # shorcuts to speed ML search; use FALSE if worried (e.g. >3 params) BioGeoBEARS_run_object$use_optimx = "GenSA" # if FALSE, use optim() instead of optimx() BioGeoBEARS_run_object$num_cores_to_use = 1 BioGeoBEARS_run_object$force_sparse = FALSE # force_sparse=TRUE causes pathology & isn't much faster at this scale # This function loads the dispersal multiplier matrix etc. from the text files into the model object. Required for these to work! # (It also runs some checks on these inputs for certain errors.) BioGeoBEARS_run_object = readfiles_BioGeoBEARS_run(BioGeoBEARS_run_object) # Divide the tree up by timeperiods/strata (uncomment this for stratified analysis) #BioGeoBEARS_run_object = section_the_tree(inputs=BioGeoBEARS_run_object, make_master_table=TRUE, plot_pieces=FALSE) # The stratified tree is described in this table: #BioGeoBEARS_run_object$master_table # Good default settings to get ancestral states BioGeoBEARS_run_object$return_condlikes_table = TRUE BioGeoBEARS_run_object$calc_TTL_loglike_from_condlikes_table = TRUE BioGeoBEARS_run_object$calc_ancprobs = TRUE # get ancestral states from optim run # Set up BAYAREALIKE model # No subset sympatry BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["s","type"] = "fixed" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["s","init"] = 0.0 BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["s","est"] = 0.0 # No vicariance BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["v","type"] = "fixed" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["v","init"] = 0.0 BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["v","est"] = 0.0 # No jump dispersal/founder-event speciation # BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["j","type"] = "free" # BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["j","init"] = 0.01 # BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["j","est"] = 0.01 # Adjust linkage between parameters BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["ysv","type"] = "1-j" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["ys","type"] = "ysv*1/1" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["y","type"] = "1-j" # Only sympatric/range-copying (y) events allowed, and with # exact copying (both descendants always the same size as the ancestor) BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["mx01y","type"] = "fixed" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["mx01y","init"] = 0.9999 BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["mx01y","est"] = 0.9999 # Check the inputs check_BioGeoBEARS_run(BioGeoBEARS_run_object) runslow = TRUE resfn = "Squamata_BAYAREALIKE_M0_unconstrained_v1.Rdata" if (runslow) { res = bears_optim_run(BioGeoBEARS_run_object) res save(res, file=resfn) resBAYAREALIKE = res } else { # Loads to "res" load(resfn) resBAYAREALIKE = res } ####################################################### # Run BAYAREALIKE+J ####################################################### BioGeoBEARS_run_object = define_BioGeoBEARS_run() BioGeoBEARS_run_object$trfn = trfn BioGeoBEARS_run_object$geogfn = geogfn BioGeoBEARS_run_object$max_range_size = max_range_size BioGeoBEARS_run_object$min_branchlength = 0.000001 # Min to treat tip as a direct ancestor (no speciation event) BioGeoBEARS_run_object$include_null_range = TRUE # set to FALSE for e.g. DEC* model, DEC*+J, etc. # (For DEC* and other "*" models, please cite: Massana, Kathryn A.; Beaulieu, # Jeremy M.; Matzke, Nicholas J.; O’Meara, Brian C. (2015). Non-null Effects of # the Null Range in Biogeographic Models: Exploring Parameter Estimation in the # DEC Model. bioRxiv, http://biorxiv.org/content/early/2015/09/16/026914 ) # Also: search script on "include_null_range" for other places to change # Set up a time-stratified analysis: #BioGeoBEARS_run_object$timesfn = "timeperiods.txt" #BioGeoBEARS_run_object$dispersal_multipliers_fn = "manual_dispersal_multipliers.txt" #BioGeoBEARS_run_object$areas_allowed_fn = "areas_allowed.txt" #BioGeoBEARS_run_object$areas_adjacency_fn = "areas_adjacency.txt" #BioGeoBEARS_run_object$distsfn = "distances_matrix.txt" # See notes on the distances model on PhyloWiki's BioGeoBEARS updates page. # Speed options and multicore processing if desired BioGeoBEARS_run_object$on_NaN_error = -1e50 # returns very low lnL if parameters produce NaN error (underflow check) BioGeoBEARS_run_object$speedup = TRUE # shorcuts to speed ML search; use FALSE if worried (e.g. >3 params) BioGeoBEARS_run_object$use_optimx = "GenSA" BioGeoBEARS_run_object$num_cores_to_use = 1 BioGeoBEARS_run_object$force_sparse = FALSE # force_sparse=TRUE causes pathology & isn't much faster at this scale # This function loads the dispersal multiplier matrix etc. from the text files into the model object. Required for these to work! # (It also runs some checks on these inputs for certain errors.) BioGeoBEARS_run_object = readfiles_BioGeoBEARS_run(BioGeoBEARS_run_object) # Divide the tree up by timeperiods/strata (uncomment this for stratified analysis) #BioGeoBEARS_run_object = section_the_tree(inputs=BioGeoBEARS_run_object, make_master_table=TRUE, plot_pieces=FALSE) # The stratified tree is described in this table: #BioGeoBEARS_run_object$master_table # Good default settings to get ancestral states BioGeoBEARS_run_object$return_condlikes_table = TRUE BioGeoBEARS_run_object$calc_TTL_loglike_from_condlikes_table = TRUE BioGeoBEARS_run_object$calc_ancprobs = TRUE # get ancestral states from optim run # Set up BAYAREALIKE+J model # Get the ML parameter values from the 2-parameter nested model # (this will ensure that the 3-parameter model always does at least as good) dstart = resBAYAREALIKE$outputs@params_table["d","est"] estart = resBAYAREALIKE$outputs@params_table["e","est"] jstart = 0.0001 # Input starting values for d, e BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["d","init"] = dstart BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["d","est"] = dstart BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["e","init"] = estart BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["e","est"] = estart # No subset sympatry BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["s","type"] = "fixed" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["s","init"] = 0.0 BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["s","est"] = 0.0 # No vicariance BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["v","type"] = "fixed" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["v","init"] = 0.0 BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["v","est"] = 0.0 # *DO* allow jump dispersal/founder-event speciation (set the starting value close to 0) BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["j","type"] = "free" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["j","init"] = jstart BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["j","est"] = jstart # Under BAYAREALIKE+J, the max of "j" should be 1, not 3 (as is default in DEC+J) or 2 (as in DIVALIKE+J) BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["j","max"] = 0.99999 # Adjust linkage between parameters BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["ysv","type"] = "1-j" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["ys","type"] = "ysv*1/1" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["y","type"] = "1-j" # Only sympatric/range-copying (y) events allowed, and with # exact copying (both descendants always the same size as the ancestor) BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["mx01y","type"] = "fixed" BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["mx01y","init"] = 0.9999 BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["mx01y","est"] = 0.9999 # NOTE (NJM, 2014-04): BAYAREALIKE+J seems to crash on some computers, usually Windows # machines. I can't replicate this on my Mac machines, but it is almost certainly # just some precision under-run issue, when optim/optimx tries some parameter value # just below zero. The "min" and "max" options on each parameter are supposed to # prevent this, but apparently optim/optimx sometimes go slightly beyond # these limits. Anyway, if you get a crash, try raising "min" and lowering "max" # slightly for each parameter: BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["d","min"] = 0.0000001 BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["d","max"] = 4.9999999 BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["e","min"] = 0.0000001 BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["e","max"] = 4.9999999 BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["j","min"] = 0.00001 BioGeoBEARS_run_object$BioGeoBEARS_model_object@params_table["j","max"] = 0.99999 check_BioGeoBEARS_run(BioGeoBEARS_run_object) resfn = "Squamata_BAYAREALIKE+J_M0_unconstrained_v1.Rdata" runslow = TRUE if (runslow) { res = bears_optim_run(BioGeoBEARS_run_object) res save(res, file=resfn) resBAYAREALIKEj = res } else { # Loads to "res" load(resfn) resBAYAREALIKEj = res } pdffn = "Squamata_BAYAREALIKE_vs_BAYAREALIKE+J_M0_unconstrained_v1.pdf" pdf(pdffn, width=12, height=198) ####################################################### # Plot ancestral states - BAYAREALIKE ####################################################### analysis_titletxt ="BioGeoBEARS BAYAREALIKE on Squamata M0_unconstrained" # Setup results_object = resBAYAREALIKE scriptdir = np(system.file("extdata/a_scripts", package="BioGeoBEARS")) ##Trying something to fix the weird error that comes up from Matzke #source("http://phylo.wdfiles.com/local--files/biogeobears/BioGeoBEARS_plots_v1.R") # States res2 = plot_BioGeoBEARS_results(results_object, analysis_titletxt, addl_params=list("j"), plotwhat="text", label.offset=0.45, tipcex=0.3, statecex=0.3, splitcex=0.2, titlecex=0.8, plotsplits=TRUE, cornercoords_loc=scriptdir, include_null_range=TRUE, tr=tr, tipranges=tipranges) # Pie chart plot_BioGeoBEARS_results(results_object, analysis_titletxt, addl_params=list("j"), plotwhat="pie", label.offset=0.45, tipcex=0.3, statecex=0.3, splitcex=0.2, titlecex=0.8, plotsplits=TRUE, cornercoords_loc=scriptdir, include_null_range=TRUE, tr=tr, tipranges=tipranges) ####################################################### # Plot ancestral states - BAYAREALIKE+J ####################################################### analysis_titletxt ="BioGeoBEARS BAYAREALIKE+J on Squamata M0_unconstrained" # Setup results_object = resBAYAREALIKEj scriptdir = np(system.file("extdata/a_scripts", package="BioGeoBEARS")) # States res1 = plot_BioGeoBEARS_results(results_object, analysis_titletxt, addl_params=list("j"), plotwhat="text", label.offset=0.45, tipcex=0.3, statecex=0.3, splitcex=0.2, titlecex=0.8, plotsplits=TRUE, cornercoords_loc=scriptdir, include_null_range=TRUE, tr=tr, tipranges=tipranges) # Pie chart plot_BioGeoBEARS_results(results_object, analysis_titletxt, addl_params=list("j"), plotwhat="pie", label.offset=0.45, tipcex=0.3, statecex=0.3, splitcex=0.2, titlecex=0.8, plotsplits=TRUE, cornercoords_loc=scriptdir, include_null_range=TRUE, tr=tr, tipranges=tipranges) dev.off() cmdstr = paste("open ", pdffn, sep="") system(cmdstr) ######################################################################### ######################################################################### ######################################################################### ######################################################################### # # CALCULATE SUMMARY STATISTICS TO COMPARE # DEC, DEC+J, DIVALIKE, DIVALIKE+J, BAYAREALIKE, BAYAREALIKE+J # ######################################################################### ######################################################################### ######################################################################### ######################################################################### ######################################################################### ######################################################################### # REQUIRED READING: # # Practical advice / notes / basic principles on statistical model # comparison in general, and in BioGeoBEARS: # http://phylo.wikidot.com/advice-on-statistical-model-comparison-in-biogeobears ######################################################################### ######################################################################### # Set up empty tables to hold the statistical results restable = NULL teststable = NULL ####################################################### # Statistics -- DEC vs. DEC+J ####################################################### # We have to extract the log-likelihood differently, depending on the # version of optim/optimx LnL_2 = get_LnL_from_BioGeoBEARS_results_object(resDEC) LnL_1 = get_LnL_from_BioGeoBEARS_results_object(resDECj) numparams1 = 3 numparams2 = 2 stats = AICstats_2models(LnL_1, LnL_2, numparams1, numparams2) stats # DEC, null model for Likelihood Ratio Test (LRT) res2 = extract_params_from_BioGeoBEARS_results_object(results_object=resDEC, returnwhat="table", addl_params=c("j"), paramsstr_digits=4) # DEC+J, alternative model for Likelihood Ratio Test (LRT) res1 = extract_params_from_BioGeoBEARS_results_object(results_object=resDECj, returnwhat="table", addl_params=c("j"), paramsstr_digits=4) # The null hypothesis for a Likelihood Ratio Test (LRT) is that two models # confer the same likelihood on the data. See: Brian O'Meara's webpage: # http://www.brianomeara.info/tutorials/aic # ...for an intro to LRT, AIC, and AICc rbind(res2, res1) tmp_tests = conditional_format_table(stats) restable = rbind(restable, res2, res1) teststable = rbind(teststable, tmp_tests) ####################################################### # Statistics -- DIVALIKE vs. DIVALIKE+J ####################################################### # We have to extract the log-likelihood differently, depending on the # version of optim/optimx LnL_2 = get_LnL_from_BioGeoBEARS_results_object(resDIVALIKE) LnL_1 = get_LnL_from_BioGeoBEARS_results_object(resDIVALIKEj) numparams1 = 3 numparams2 = 2 stats = AICstats_2models(LnL_1, LnL_2, numparams1, numparams2) stats # DIVALIKE, null model for Likelihood Ratio Test (LRT) res2 = extract_params_from_BioGeoBEARS_results_object(results_object=resDIVALIKE, returnwhat="table", addl_params=c("j"), paramsstr_digits=4) # DIVALIKE+J, alternative model for Likelihood Ratio Test (LRT) res1 = extract_params_from_BioGeoBEARS_results_object(results_object=resDIVALIKEj, returnwhat="table", addl_params=c("j"), paramsstr_digits=4) rbind(res2, res1) conditional_format_table(stats) tmp_tests = conditional_format_table(stats) restable = rbind(restable, res2, res1) teststable = rbind(teststable, tmp_tests) ####################################################### # Statistics -- BAYAREALIKE vs. BAYAREALIKE+J ####################################################### # We have to extract the log-likelihood differently, depending on the # version of optim/optimx LnL_2 = get_LnL_from_BioGeoBEARS_results_object(resBAYAREALIKE) LnL_1 = get_LnL_from_BioGeoBEARS_results_object(resBAYAREALIKEj) numparams1 = 3 numparams2 = 2 stats = AICstats_2models(LnL_1, LnL_2, numparams1, numparams2) stats # BAYAREALIKE, null model for Likelihood Ratio Test (LRT) res2 = extract_params_from_BioGeoBEARS_results_object(results_object=resBAYAREALIKE, returnwhat="table", addl_params=c("j"), paramsstr_digits=4) # BAYAREALIKE+J, alternative model for Likelihood Ratio Test (LRT) res1 = extract_params_from_BioGeoBEARS_results_object(results_object=resBAYAREALIKEj, returnwhat="table", addl_params=c("j"), paramsstr_digits=4) rbind(res2, res1) conditional_format_table(stats) tmp_tests = conditional_format_table(stats) restable = rbind(restable, res2, res1) teststable = rbind(teststable, tmp_tests) ######################################################################### # ASSEMBLE RESULTS TABLES: DEC, DEC+J, DIVALIKE, DIVALIKE+J, BAYAREALIKE, BAYAREALIKE+J ######################################################################### teststable$alt = c("DEC+J", "DIVALIKE+J", "BAYAREALIKE+J") teststable$null = c("DEC", "DIVALIKE", "BAYAREALIKE") row.names(restable) = c("DEC", "DEC+J", "DIVALIKE", "DIVALIKE+J", "BAYAREALIKE", "BAYAREALIKE+J") restable = put_jcol_after_ecol(restable) restable # Look at the results!! restable teststable ####################################################### # Save the results tables for later -- check for e.g. # convergence issues ####################################################### # Loads to "restable" save(restable, file="restable_v1.Rdata") load(file="restable_v1.Rdata") # Loads to "teststable" save(teststable, file="teststable_v1.Rdata") load(file="teststable_v1.Rdata") # Also save to text files write.table(restable, file="restable.txt", quote=FALSE, sep="\t") write.table(unlist_df(teststable), file="teststable.txt", quote=FALSE, sep="\t") ####################################################### # Model weights of all six models ####################################################### restable2 = restable # With AICs: AICtable = calc_AIC_column(LnL_vals=restable$LnL, nparam_vals=restable$numparams) restable = cbind(restable, AICtable) restable_AIC_rellike = AkaikeWeights_on_summary_table(restable=restable, colname_to_use="AIC") restable_AIC_rellike = put_jcol_after_ecol(restable_AIC_rellike) restable_AIC_rellike # With AICcs -- factors in sample size samplesize = length(tr$tip.label) AICtable = calc_AICc_column(LnL_vals=restable$LnL, nparam_vals=restable$numparams, samplesize=samplesize) restable2 = cbind(restable2, AICtable) restable_AICc_rellike = AkaikeWeights_on_summary_table(restable=restable2, colname_to_use="AICc") restable_AICc_rellike = put_jcol_after_ecol(restable_AICc_rellike) restable_AICc_rellike # Also save to text files write.table(restable_AIC_rellike, file="restable_AIC_rellike.txt", quote=FALSE, sep="\t") write.table(restable_AICc_rellike, file="restable_AICc_rellike.txt", quote=FALSE, sep="\t") # Save with nice conditional formatting write.table(conditional_format_table(restable_AIC_rellike), file="restable_AIC_rellike_formatted.txt", quote=FALSE, sep="\t") write.table(conditional_format_table(restable_AICc_rellike), file="restable_AICc_rellike_formatted.txt", quote=FALSE, sep="\t") ####################################################### # Your results should be: ####################################################### # > restable # # LnL numparams d e j # DEC -34.5 2 3.504546e-02 2.835632e-02 0.0000000 # DEC+J -20.9 3 1.000000e-12 1.000000e-12 0.1142811 # DIVALIKE -33.1 2 4.474416e-02 1.000000e-12 0.0000000 # DIVALIKE+J -21.1 3 2.001000e-09 1.000000e-12 0.1157199 # BAYAREALIKE -40.3 2 1.738085e-02 3.040188e-01 0.0000000 # BAYAREALIKE+J -21.6 3 1.000000e-12 1.000000e-12 0.1081158 ####################################################### # The p-value of the LRT (Likelihood Ratio Test) tells you whether or not you can reject the # null hypothesis that DEC and DEC+J confer equal likelihoods on the data # # AIC and AICc model weights are also shown, giving a sense of the relative probability of the two models. # # (One could easily do model weights between all 6 models, but this is not done here; s # see Brian O'Meara's AIC webpage: http://www.brianomeara.info/tutorials/aic ) ####################################################### # > teststable # # alt null LnLalt LnLnull DFalt DFnull DF Dstatistic pval test tail AIC1 AIC2 AICwt1 AICwt2 AICweight_ratio_model1 AICweight_ratio_model2 # 1 DEC+J DEC -20.95 -34.54 3 2 1 27.19 1.8e-07 chi-squared one-tailed 47.9 73.08 1.00 3.4e-06 294893 3.4e-06 # 11 DIVALIKE+J DIVALIKE -21.09 -33.15 3 2 1 24.13 9.0e-07 chi-squared one-tailed 48.17 70.3 1.00 1.6e-05 63797 1.6e-05 # 12 BAYAREALIKE+J BAYAREALIKE -21.09 -33.15 3 2 1 24.13 9.0e-07 chi-squared one-tailed 48.17 70.3 1.00 1.6e-05 63797 1.6e-05 ####Trim for plotting node.states <- resBAYAREALIKEj$ML_marginal_prob_each_state_at_branch_bottom_below_node#tip and node states dim(node.states) tail(node.states) states <- node.states[5417:10831,] state.codes <- max.col(states) state.colors <- c(NA,"blue","green","red","black","purple","yellow4","white") tr$node.label <- state.colors[state.codes]; tr$node.label[1] <- "red" plot(tr,show.tip.label = FALSE,no.margin=TRUE) nodelabels(pch=19,col=tr$node.label) ###Trim with phytools library(phytools) ## get all node heights H<-nodeHeights(tr) ## time from the root t<-max(H)-66 ## identify all edges that cross 66 mybp h1<-which(H[,1]t) ii<-intersect(h1,h2) ## all daughter nodes of those edges nodes<-tr$edge[ii,2] ## internal phytools function getDescendants<-phytools:::getDescendants ## find all descendants from each edge tips<-lapply(nodes,getDescendants,tree=tr) ## find all tips to keep tips<-tr$tip.label[sapply(tips,function(x,y) x[x<=Ntip(y)][1],y=tr)] ## drop all the others tr.trim<-drop.tip(tr,setdiff(tr$tip.label,tips)) #plot pdf(file="Barger_Trimmed_Tree_Figure.pdf",height = 11,width = 8.5) plotTree(tr.trim,fsize=0.45,ftype="i") lines(c(t,t),par()$usr[3:4],lty="dashed",col="red") nodelabels(pch=19,col=tr.trim$node.label) geo.legend()#why dont labels appear? cladelabels(node=235,text = "Dibamia",offset = 10.5) cladelabels(node=188,text = "Gekkota",offset = 9) cladelabels(node=177,text = "Scincomorpha",offset = 10.5) cladelabels(node=165,text = "Laterata",offset = 9) cladelabels(node=160,text = "Anguimorpha",offset = 10.5) cladelabels(node=145,text = "Iguania",offset = 9) cladelabels(node=125,text = "Serpentes",offset = 10.5) dev.off() #