This is a tutorial vignette to provide a quick and easy introduction to the use of MonoPhy. It will make use of the inbuilt example files and lead through the most important functions of the package.
In order to be aware of discrepancies between a newly generated phylogeny and the current taxonomy, it is necessary to assess monophyly of the taxa in the tree. MonoPhy allows doing this in a quick and simple way, both using the phylogeny only and including a file assigning tips to taxonomic groups. Notably, such a file can contain any type of information for which to test monophyly in a tree ( e.g., traits or geographic occurrence), as long as attention is paid to that the assessment makes sense biologically.
If - for any reason - you would want to install the development
version from GitHub, I suggest doing so by installing it temporarily
with the help of the package devtools
:
# 1. Install package 'devtools' (if not already installed):
install.packages("devtools")
# 2. Load 'devtools' and temporarily install and load 'MonoPhy' in developers mode:
library(devtools)
dev_mode(on=T)
install_github("oschwery/MonoPhy") # install the package from GitHub
library(MonoPhy) # load the package
#3. Leave developers mode after done trying out 'MonoPhy':
dev_mode(on=F)
# the package will not stay on your system permanently like that, which make sense in case of the
# development version, as opposed to the stable version
When we load the package, all its functions and the other required packages are imported.
The package comes with example files for you to try out its functions, which will be used throughout this tutorial. The phylogeny is of the plant family Ericaceae, as published in Schwery et al. (2015) pruned down to 77 taxa. Two taxon files assign tribes or both tribes and subfamilies to the tips.
It is generally a good idea (especially with own data) to check whether the format of the data is correct:
##
## Phylogenetic tree with 77 tips and 76 internal nodes.
##
## Tip labels:
## Agapetes_buxifolia, Agapetes_hosseana, Agapetes_serpens, Allotropa_virgata, Andromeda_polifolia, Bruckenthalia_spiculifolia, ...
##
## Rooted; includes branch lengths.
## V1 V2
## 1 Agapetes_buxifolia Vaccinieae
## 2 Agapetes_hosseana Vaccinieae
## 3 Agapetes_serpens Vaccinieae
## 4 Allotropa_virgata Monotropeae
## 5 Andromeda_polifolia Andromedeae
## 6 Bruckenthalia_spiculifolia Ericeae
## V1 V2 V3
## 1 Agapetes_buxifolia Vaccinieae Vaccinioideae
## 2 Agapetes_hosseana Vaccinieae Vaccinioideae
## 3 Agapetes_serpens Vaccinieae Vaccinioideae
## 4 Allotropa_virgata Monotropeae Monotropoideae
## 5 Andromeda_polifolia Andromedeae Vaccinioideae
## 6 Bruckenthalia_spiculifolia Ericeae Ericoideae
If you want to analyze your own data (which should ultimately be the goal), you can load your phylogeny like this:
At this point, the package requires the input tree to be rooted, though it may be multifurcating; also, it can only handle single input trees so far. This may change in the future. Polytomies will be dealt with in a conservative way: if different taxa occur in a polytomy, it will be assumed that they are non-monophyletic.
The taxonomy file should be a data frame with or without header and one row per tip in the phylogeny. The first column should be the tip names, any further column should assign the respective tips to taxonomic groups, in the format of one column per group (testing monophyly on several taxonomic levels is possible). If the file has a header, the names therein will be used to name the taxlevels within the function. If it is unknown or not applicable what group a tip belongs to on a certain taxonomic level, it should be encoded as ‘NA’. You can load the taxonomy file like this:
To check again whether the format of the data is correct:
The command for the main analysis-step is
AssessMonophyly
. This will check the monophyly of all taxa
in the tree, identify which intruders and outliers are responsible for
the non-monophyly of a taxon and determine their status for latter
plotting. Depending on the number of tips in the tree and the number of
monophyly-issues, this step will take more or less time. For the example
files, this step should only take seconds, for a few thousand tips a
couple of minutes, but for a conflict-rich tree with several 10k tips it
could easily end up being a few hours. Accessing the information
afterwards, however, is fairly quick.
If we run the analysis using only the tree, the function will check whether the tip labels are in the format Genus_species, and if so, will extract the genus name from each tip label and use it as the taxonomic group associated to this tip.
The resulting output object will be a list, which will contain all the output information for all taxon levels in a nested fashion. We will explore in the following how to access this information effectively.
If the tip labels have a format different from Genus_species, or if we want to assess a different taxonomic level, we can do that by adding a taxonomy file to the command. The taxonomy file should be a simple table (data frame, maybe easiest based off a .csv file) with or without header, at least two columns and one row per tip. The first column contains the tip labels and all further columns (one or more) the names of the taxa associated to the respective tip, whereas every column stands for a different taxon level (the file has a header, its entries will be used to name the levels). The order of tip names in the file can be different from the order of the tip labels in the tree, but they have to contain the exact same names. If taxonomic levels are unknown for certain tips, they can be coded as NAs (but they cannot stay empty). Those tips will be considered when assessing monophyly of other groups, but the monophyly of the NA group will not be assessed.
If a taxonomy file cannot be generated easily, specifying taxonomy as
taxize
allows to use the package with the same name to
download taxonomic names of groups indicated under
taxizelevel
from the online databases 'ncbi'
,
'itis'
or 'both'
, as set under
taxizedb
and taxizepref
. The downloaded
records will then be used like a taxonomy file.
Note: While the function is implemented in a way to
remove duplicates from both databases and only retain the ones that
yielded a record, specifying 'both'
can lead to errors by
the taxize
package. Also be aware that - compared to the
rest of the function - downloading taxonomic information can take a fair
amount of time for medium sized trees already.
There are a few remaining specifications for this function.
verbosity
allows to customize the maximal number of
intruders/outliers to be displayed in the results table.
outliercheck
, if set to TRUE
, will let the
function consider taxon members which are ‘too far away’ in the tree
from the rest of their taxon as outliers, instead of all tips ‘in
between them’ as intruders, thereby hopefully making the result
biologically more meaningful. It will start to look for outliers if the
ratio of taxon members in a clade is below the value specified as
outlierlevel
and will try and find a ‘core clade’ with a
ratio higher than that. The arguments taxask
and
taxverbose
allow to adjust the settings of the called
taxize
function tax_name
:
taxverbose
allows to set whether the function should
display which taxon is currently queried and whether an entry is found;
taxask
allows to set whether the function prompts the user
to decide among several potential matches in the database, or to just
pick the most likely one instead.
The default values for this command are as follows:
To get a first look on the results, we can pull the summary table out of the output object:
## $Genera
## Taxa Tips
## Total 32 77
## Monophyletic 9 25
## Non-Monophyletic 6 35
## Monotypic 17 17
## Intruder 7 11
## Outlier 1 2
We can now see in the first column how many taxa are either monophyletic, non-monophyletic or monotypic (consisting of only one representative), as well as how many have outliers or are intruders to another taxon. In the second column, we can see how many of the tips fall in those respective categories.
If we used a taxonomy file and had several taxonomic levels, the
summary and result functions will by default return all of them. If we
only want to look at a specific one, we can specify the number of the
one we want under taxlevels
.
GetResultMonophyly(solution1, taxlevels=2) # pull out summary only for taxlevel 2, subfamilies in this case
## $`2`
## Monophyly MRCA #Tips Delta-Tips #Intruders
## Vaccinioideae No 89 34 28 2
## Monotropoideae Yes 80 10 0 0
## Ericoideae No 123 23 1 1
## Cassiopoideae Yes 146 5 0 0
## Enkianthoideae Yes 150 5 0 0
## Intruders #Outliers Outliers
## Vaccinioideae Ericoideae, Cassiopoideae 0
## Monotropoideae NA
## Ericoideae Vaccinioideae 0
## Cassiopoideae NA
## Enkianthoideae NA
##
## $Taxlevel_2
## Monophyly MRCA #Tips Delta-Tips #Intruders
## Vaccinioideae No 89 34 28 2
## Monotropoideae Yes 80 10 0 0
## Ericoideae No 123 23 1 1
## Cassiopoideae Yes 146 5 0 0
## Enkianthoideae Yes 150 5 0 0
## Intruders #Outliers Outliers
## Vaccinioideae Ericoideae, Cassiopoideae 0
## Monotropoideae NA
## Ericoideae Vaccinioideae 0
## Cassiopoideae NA
## Enkianthoideae NA
The result table shows us the analysis outcomes for each taxonomic unit considered. The row ‘Monophyly’ states for each taxon whether it is monophyletic, ‘MRCA’ gives the node number of the most recent common ancestor of all its members, ‘#Tips’ gives the number of tips assigned to this taxon, and ‘Delta-Tips’ gives the number of tips that do not belong to that taxon, but which are also descendants of its MRCA. The columns ‘#Intruders’ and ‘#Outliers’ tell us how many other taxa or tips are intruders or outliers for this taxon respectively. ‘Intruders’ and ‘Outliers’ give us their names.
In order to really dig into the analysis outputs, we can access information on which taxa and tips cause the monophyly issues as either intruders or outliers and which nodes have been inferred as MRCA of each taxon.
When exploring intruders, we can either list them for all taxa or limit the list to taxa we’re interested in, e.g. only for the genus Erica:
## $Genera
## $Genera$Erica
## [1] "Bruckenthalia"
We learn that the genus Bruckenthalia invades Erica, which turns out not to be problematic, as Bruckenthalia is now classified to belong to Erica as well.
Similarly, if we have multiple taxonomic levels, we can limit the output to the one of interest:
GetIntruderTips(solution1, taxa="Ericoideae", taxlevels=2) # get list of species causing monophyly-issues for the subfamily Ericoideae
## $`2`
## $`2`$Ericoideae
## [1] "Rhodothamnus_chamaecistus"
##
##
## $Taxlevel_2
## $Taxlevel_2$Ericoideae
## [1] "Rhodothamnus_chamaecistus"
This works similarly for MRCA-nodes, outlier tips and outlier taxa (note that the later cannot be constrained to focal taxa, because a tip can only be an outlier to its own taxon). Instead of numbers or ‘ALL’, we could also select taxlevels using their names.
## $Taxlevel_1
## MRCA
## Vaccinieae 91
## Monotropeae 81
## Andromedeae 91
## Ericeae 125
## Bryantheae 137
## Cassiopoideae 146
## Pyroleae 82
## Enkianthoideae 150
## Phyllodoceae 139
## Oxydendreae NA
##
## $Taxlevel_2
## MRCA
## Vaccinioideae 89
## Monotropoideae 80
## Ericoideae 123
## Cassiopoideae 146
## Enkianthoideae 150
Note: The NA
for Oxydendreae reflects
that it is monotypic and thus doesn’t have an MRCA.
## $Genera
## [1] "Vaccinium"
## $Taxlevel_1
## $Taxlevel_1$Andromedeae
## [1] "Vaccinium_vitis_idaea"
##
##
## $Taxlevel_2
## list()
Note: list()
of course means that there
aren’t any outliers in Taxlevel_2.
Needless to say, the most intuitive way to get an impression of the issues in the monophyly within a phylogeny is to visually inspect it. Thus, there are a number of ways to look at our results as well.
The monophyly plot is the standard plot for this package. It will colour tips (and clades) according to their monophyly status, allowing to quickly spot areas of the tree where problems occur. The standard colours are:
A number of other ColorBrewer palettes are available (as listed in helpfile) and using customized colours is possible as well. By default, the tree will be ladderized.
The simplest way of plotting monophyly is like this:
This shows us the monophyly situation on the genus level. It is easy
to see how Orthilia invades Pyrola,
Kalmiopsis invades Phyllodoce, Bruckenthalia
invades Erica and how Dimorphanthera and
Paphia reciprocally invade each other. We further see how
Vaccinium is invaded by Agapetes and
Gaylussacia, while having two outlier species of its own as
well. Note how a more conservative ( i.e. higher)
outlierlevel
would tell us that only Gaylussacia
invades Vaccinium, which would then have Vaccinium
bracteatum as additional outlier instead.
This rather auxiliary plot type allows viewing clades coloured by the
taxon they belong to. Here we want to look at a different
taxonomic level, the subfamilies, hence we can specify
in the command to display taxlevels=2
(as subfamilies was
the second taxonomy column in our input file) and pick the output object
solution1
, which contains the results of the analysis
incorporating the taxonomy file. The default colours are
rainbow
, which means that every taxon will get a different
colour from the rainbow spectrum.
## Warning in fastAnc(tax.tree, tipdataT, vars = FALSE, CI = FALSE): x should be a vector with names corresponding to the taxon labels of the tree.
## Assuming x is in the order of tree$tip.label (this is seldom true).
This plot shows us nicely how the subfamilies are mostly monophyletic, apart from one rogue in red, which is Rhodothamnus chamaecystus, which notably was mislabeled as a member of the Vaccinioideae (whereas in reality - belonging to Ericoideae - it is in the right place).
This plot type simply combines the two previous ones and displays them on two mirrored trees. We use the subfamilies again in this case.
## Warning in fastAnc(tax.tree, tipdataT, vars = FALSE, CI = FALSE): x should be a vector with names corresponding to the taxon labels of the tree.
## Assuming x is in the order of tree$tip.label (this is seldom true).
Seeing the previous plot mirrored with the corresponding monophyly
plot lets us understand how the whole Ericoideae and Cassiopoideae come
out as intruders to Vaccinioideae: The intruder Rhodothamnus
chamaecystus pulls the MRCA node of the Vaccinioideae down to
include both other subfamilies. Once again, a more conservative
outlierlevel
would have led to the biologically more
meaningful result that only Rhodothamnus is an outlier to
Vaccinioideae (and an intruder to Ericoideae), while everything else is
well.
For a more condensed view on the monophyly issues in your tree and
who is causing them, you might want to choose the intruder plot, which
will especially highlight intruders and outliers and which taxon they
belong to. In order to focus the plot on the issues even more, we set
monocoll=TRUE
, to collapse monophyletic
taxa to be represented by one tip each. This time, we display
tribes. The default colouring is:
PlotMonophyly(solution1, Ericactree, taxlevels=1, plot.type='intruders', monocoll=TRUE, cex=0.5, label.offset=5)
Collapsing all monophyletic tribes slimmed this plot down and increased the overview. We immediately see that the issues are confined to the Vaccinieae and their sister clade, the Andromedeae, and the colouration reveals that Andromeda polifolia, Vaccinium vitis-ideae and Zenobia pulverulenta are causing it. Apparently, Andromeda and the Vaccinium are supposed to belong to the same tribe (Andromedeae), whereas Zenobia should belong to a different one (being an intruder to Andromedeae from Vaccinieae). The solution behind this issue is that the tribe names assigned to Vaccinium vitis-ideae and Zenobia pulverulenta where (intentionally) switched.
Note: Intruders are coloured using
rainbow
as well, but the palette will be newly created and
the colours will not correspond to the ones in the taxonomy plot.
A difficulty for viewing phylogenies in R is that trees can be too
large to see much detail in an R plotting window. To this end, we can
choose to print the plot directly to a PDF file instead, in which we can
then easily search and zoom into the desired portions of the tree. To
achieve this, we simply set PDF=TRUE
and set our desired
filename in PDF_filename='ourdesiredfilename.pdf'
. Space
can additionally be saved by using monocoll=TRUE
. The size
of the PDF can be specified using PDF_width
and
PDF_height
, the default for which is
"auto"
.
Note: Be aware that plotting very large trees can take quite some time, in some cases longer than running the main analysis.
Here two examples that are printed to PDF, first a monophyly plot with collapsed monophyletic clades on genus level:
PlotMonophyly(solution0, Ericactree, taxlevels=1, plot.type='monophyly', monocoll=TRUE,
ladderize=TRUE, PDF=TRUE, PDF_filename='Monophylyplot_Ericac_Example.pdf')
and second an intruder plot on subfamily level. A good idea for large
trees is, to display them in circular shape using
type="fan"
:
PlotMonophyly(solution1, Ericactree, taxlevels=2, plot.type='intruders', ladderize=TRUE, PDF=TRUE,
PDF_filename='Intruderplot_Ericac_Example.pdf', type="fan")
Note: If PDF_height
and
PDF_width
are set to "auto"
, the command will
automatically scale the PDF document to be created according to the
number of taxa in the tree. However, PDF files seem to be constrained to
a maximum size of 200 inches, and the function will thus cap the size to
that (both for automatic and manual sizes). If your tree is very large,
the resulting PDF might be difficult to inspect, and you might want to
consider chopping your tree up into subtrees to plot ( e.g.
using treeSlice
from the package
phytools
).
Also, if the automatic scaling moves tip labels etc. in a way you don’t like, you can adjust most parameters by specifying the respective arguments yourself. More details on that can be found in the helpfiles.
Further information on all the functions of the package and their use
can be found in the helpfiles help(package=MonoPhy)
. For
any further issues and questions send an email with subject ‘MonoPhy
support’ to [email protected]
.
The data for the examples is based on:
Schwery, O., Onstein, R. E., Bouchenak-Khelladi, Y., Xing, Y., Carter, R. J. and Linder, H. P. (2015), As old as the mountains: the radiations of the Ericaceae. New Phytologist. doi: 10.1111/nph.13234 Link to PDF