tree_additive {bnpsd}R Documentation

Calculate additive edges for a coancestry tree, or viceversa


A coancestry tree has IBD probabilities as edge values, which describe how each child and parent subpopulation in the tree is related. This means that each parameter is relative to its parent subpopulation (varies per edge), and they are not in general IBD probabilities from the root. This function computes "additive" edges that corresponds more closely with the coancestry matrix of this tree, which gives parameters relative to the root (ancestral) population (see details below). The additive edges are computed on a new element of the tree phylo object, so they do not overwrite the probabilistic edges. The reverse option assumes that the main edges of the phylo object are additive edges, then calculates the probabilistic edges and stores as the main edges and moves the original additive edges on the new element.


tree_additive(tree, rev = FALSE, force = FALSE)



The coancestry tree with either probabilistic edges (if rev = FALSE) or additive edges (if rev = TRUE) as the main edges (stored in tree$edge.length). Must be a phylo object from the ape package (see ape::read.tree()). This tree may have a valid root edge (non-NULL tree$root.edge between 0 and 1), which is incorporated in the output calculations. Function stops if the input data is not valid. Probabilistic edges are valid if and only if they are all between zero and one. Additive edges are valid if and only if they are all non-negative and the sum of edges between the root and each tip (leaf node) does not exceed 1.


If FALSE (default), assumes the main edges are probabilistic values, and calculates additive values. If TRUE, assumes main edges are additive values, and calculates probabilistic values.


If FALSE (default), function stops if input tree already has additive edges (if tree$edge.length.add is not NULL). If TRUE, these values are ignored and overwritten.


The calculation takes into account that total coancestries are non-linear combinations of the per-edge coancestries. For example, if the root node is A, and subpopulation C is connected to A only through an internal node B, then its total self-coancestry coanc_A_C relative to A is given by coanc_A_B (the coancestry between A and B) and coanc_B_C (the coancestry between B and C) by coanc_A_C = coanc_A_B + coanc_B_C * ( 1 - coanc_A_B ). This transformation ensures that the total coancestry is a probability that does not exceed one even when the per-edge coancestries sum to a value greater than one. The "additive" edge for B and C is coanc_B_C * ( 1 - coanc_A_B ), so it is the probabilistic edge coanc_B_C shrunk by 1 - coanc_A_B, which can then just be added to the parent edge coanc_A_B to give the total coancestry coanc_A_C. This transformation is iterated for all nodes in the tree, noting that roots B connected to the root node A have equal probabilistic and additive edges coanc_A_B (unless the tree has a root edge, in which case that one is used to transform as above), and the edge of a node C not directly connected to a root uses the calculated edge coanc_A_C as above to shrink its children's edges into the additive scale.


The input phylo object extended so that the main edges (tree$edge.length) are probabilistic edges, and the additive edges are stored in tree$edge.length.add. This is so for both values of rev

See Also

coanc_tree(), the key application facilitated by additive edges.


# for simulating a tree with `rtree`

# SETUP: number of tip subpopulations
k <- 5
# simulate a random tree
# edges are drawn from Uniform(0, 1), so these are valid probabilistic edges
tree <- rtree( k )
# inspect edges

# RUN calculate additive edges (safe to overwrite object)
tree <- tree_additive( tree )
# inspect edges again
# probabilistic edges are still main edges:
# additive edges are here

# let's go backwards now, starting from the additive edges
# these are harder to simulate, so let's copy the previous value to the main edges
tree$edge.length <- tree$edge.length.add
# and delete the extra entry (if it's present, function stops)
tree$edge.length.add <- NULL
# inspect before

# RUN reverse version (safe to overwrite object again)
tree <- tree_additive( tree, rev = TRUE )
# inspect after
# probabilistic edges are main edges:
# additive edges (previously main edges) were moved here

[Package bnpsd version 1.3.13 Index]