Phylogenetic diversity

When both Diversity and Phylo are loaded, we generate Phylogenetic diversity measures, based on Faith PD and extended by Chao.

Usage

Using the functionality in the package is simple:

  • Create a tree (using our Phylo package)
  • Create a PhyloBranches (AbstractTypes subtype) object from it
  • Create a Metacommunity from that
  • Calculate diversity!
julia> using Diversity, Phylo
julia> species = ["Dog", "Human", "Cat"]3-element Vector{String}: "Dog" "Human" "Cat"
julia> tree = RootedTree(species)RootedTree with 3 tips and 3 roots. Leaf names are Dog, Human and Cat 3 nodes: [RecursiveNode{OneRoot} 'Dog', an isolated node with no connections, RecursiveNode{OneRoot} 'Human', an isolated node with no connections and RecursiveNode{OneRoot} 'Cat', an isolated node with no connections] 0 branches: [] Node records: "Dog" => Dict{String, Any}() ... "Cat" => Dict{String, Any}()
julia> internal = createnode!(tree)unattached node 'Node 4'
julia> createbranch!(tree, internal, "Dog", 1.0)branch '1'
julia> createbranch!(tree, internal, "Human", 1.0)branch '2'
julia> root = createnode!(tree)unattached node 'Node 5'
julia> createbranch!(tree, root, internal, 1.0)branch '3'
julia> createbranch!(tree, root, "Cat", 2.0)branch '4'
julia> ph = PhyloBranches(tree)DiversityPhyloExt.PhyloBranches{RootedTree}(RootedTree with 3 tips and 1 root. Leaf names are Dog, Human and Cat 5 nodes: [RecursiveNode{OneRoot} 'Dog', a leaf with an incoming connection (branch 1), RecursiveNode{OneRoot} 'Human', a leaf with an incoming connection (branch 2), RecursiveNode{OneRoot} 'Cat', a leaf with an incoming connection (branch 4), RecursiveNode{OneRoot} 'Node 4', an internal node with 1 inbound and 2 outbound connections (branches 3 and [1, 2]) and RecursiveNode{OneRoot} 'Node 5', a root node with 2 outbound connections (branches [3, 4])] 4 branches: [RecursiveBranch{OneRoot} 1, from node 'Node 4' to node 'Dog' (length 1.0), RecursiveBranch{OneRoot} 2, from node 'Node 4' to node 'Human' (length 1.0), RecursiveBranch{OneRoot} 3, from node 'Node 5' to node 'Node 4' (length 1.0) and RecursiveBranch{OneRoot} 4, from node 'Node 5' to node 'Cat' (length 2.0)] Node records: "Dog" => Dict{String, Any}() ... "Node 5" => Dict{String, Any}() , 3, 5, ["Dog", "Human", "Cat"], ["Dog : 1", "Dog : 3", "Human : 2", "Human : 3", "Cat : 4"], [1.0 0.0 0.0; 1.0 0.0 0.0; … ; 0.0 1.0 0.0; 0.0 0.0 2.0], [0.5 0.5 … 0.0 0.0; 0.5 0.5 … 0.5 0.0; … ; 0.5 0.5 … 0.5 0.0; 0.0 0.0 … 0.0 0.5])
julia> metaphylo = Metacommunity([0.4, 0.3, 0.3], ph)Metacommunity{Float64, Vector{Float64}, Matrix{Float64}, DiversityPhyloExt.PhyloBranches{RootedTree}, Onecommunity} with 5 branches in 1 subcommunity measuring Phylogenetic Branch diversity. Branch names: Dog : 1, Dog : 3, Human : 2, Human : 3, Cat : 4 Subcommunity names: 1
julia> meta_gamma(metaphylo, 0)1×8 DataFrame Row div_type measure q type_level type_name partition_l String String Int64 String String String ⋯ ─────┼────────────────────────────────────────────────────────────────────────── 1 │ Phylogenetic Branch Gamma 0 types metacommuni ⋯ 3 columns omitted

The tree above is built explicitly so that the numbers on this page are stable; rand(Nonultrametric(species)) will give you a random tree to experiment with instead.

Raw and processed types

Diversity is measured over the branches of the tree rather than over the species, since that is what carries the evolutionary history. The species you supplied are still available as the raw types, and the branches are the processed types — which is what the raw argument to the accessors selects:

julia> gettypenames(metaphylo, true)3-element Vector{String}:
 "Dog"
 "Human"
 "Cat"
julia> counttypes(metaphylo, true)3
julia> counttypes(metaphylo, false)5

Faith's PD

Faith's phylogenetic diversity is the older, historical measure: the total length of the branches of the tree spanned by the species present, with no normalisation. It lives in Diversity.Ecology with the other classical indices, but works only on a metacommunity built over the PhyloBranches this extension supplies — the calculation depends on how that type in particular maps leaf abundances onto branches — and so appears only once Phylo is loaded:

julia> using Diversity.Ecology: faith_pd, generalisedfaith_pd
julia> generalisedfaith_pd(metacommunityDiversity, metaphylo)[!, :diversity]1-element Vector{Float64}: 5.0

The tree above has branches of length 1, 1, 1 and 2, so its total is 5.0.

There is no q to give it, and the output has no q column: Faith's PD is the q = 0 case by definition, so there is no profile to ask for. It also does not depend on the abundances at all, only on which species are present — which is exactly what distinguishes it from the framework's own q = 0 diversity:

julia> generalisedfaith_pd(metacommunityDiversity,
                           Metacommunity([0.98, 0.01, 0.01], ph))[!, :diversity]1-element Vector{Float64}:
 5.0
julia> meta_gamma(Metacommunity([0.98, 0.01, 0.01], ph), 0)[!, :diversity]1-element Vector{Float64}: 2.5

The first is unchanged, because the same three species are still there. The second is not, because it measures diversity per unit of branch length — the two differ by exactly the scale factor the phylogenetic types carry.

With several subcommunities, faith_pd gives the PD of each one in isolation:

julia> faith_pd(Metacommunity([0.4 0.0; 0.1 0.2; 0.0 0.3], ph))[!,
                                                                [:partition_name,
                                                                 :diversity]]2×2 DataFrame
 Row  partition_name  diversity 
      String          Float64   
─────┼───────────────────────────
   1 │ 1                     3.0
   2 │ 2                     4.0