---
title: "treestructure applied to structured coalescent simulation"
author: "Erik Volz"
date: "`r Sys.Date()`"
output:
  rmarkdown::html_vignette:
  #rmarkdown::html_vignette
  #bookdown::pdf_book:
    toc: TRUE
pkgdown:
  as_is: true
fontsize: 12pt
vignette: >
  %\VignetteIndexEntry{treestructure applied to structured coalescent simulation}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.width = 7,
  fig.height = 11,
  warning = FALSE,
  message = FALSE
)
```


# Structured coalescent simulation

This example shows the function `trestruct` applied to a simulated structured
coalescent tree that includes samples from a large constant size population and
samples from three small "outbreaks" which are growing exponentially.
These simulations were generated with the [phydynR package](https://emvolz-phylodynamics.github.io/phydynR/).

```{r message=FALSE}
library(ape)
library(treestructure)
library(ggtree)
```

Load the tree:

```{r}
( tree <- ape::read.tree( system.file('sim.nwk', package = 'treestructure') ) )
```


Note that the tip labels corresponds to the deme of each sample.
'1' is the constant size reservoir, and '0' is the exponentially growing deme.


This will run the `treestructure` algorithm under default settings:
```{r message=FALSE}
s <- trestruct( tree )
```

The `treestructure` algorithm searches from root to tips of the phylogenetic tree.
The message printed on screen, `Finding splits under nodes`, reports which nodes
the algorithm is currently testing.

By default `trestruct` calibrates the split threshold to a target false discovery
rate (`fdr = 0.2`), so that the expected proportion of spuriously designated clusters
is controlled across the whole tree. The printed output reports this target and a
global test for whether the tree has any structure at all:

```{r}
print(s)
```

## Plotting results

The default plotting behavior uses the `ggtree` package if available.
```{r message=FALSE}
plot(s)  + ggtree::geom_tiplab()
```

If not, or if desired, `ape` plots are available
```{r}
plot( s, use_ggtree = FALSE )
```


For subsequent analysis, you may want to turn the `treestructure` result into a
dataframe:
```{r}
structureData <- as.data.frame( s )
head( structureData )
```

Each cluster and partition assignment is stored as a factor. You could use `split`
to get a data frame for each partition.
Suppose we want a tree corresponding to partition 1:
```{r}
with ( structureData,
       ape::keep.tip(s$tree, taxon[ partition==1 ] )
       ) -> partition1
partition1
plot(partition1)
```


# Parameter choice and number of clusters

Two things have the largest influence on the number of clusters.

1. `minCladeSize` controls the smallest allowed cluster in terms of the number of
tips; the default is 10. With a smaller value, smaller clusters may be detected, but
computation time increases. For example, structure that exists in clades smaller than
`minCladeSize` will not be detected regardless of the threshold, so lowering it can
reveal finer structure:

```{r message=FALSE}
trestruct( tree, minCladeSize = 5 )
```

2. The split threshold — how readily a clade is designated a new cluster. By default
this is set by a false discovery rate (`fdr`); alternatively it can be set by a
subjective significance `level`, or that `level` chosen automatically with the CH
index.

### False discovery rate (default)

By default the threshold is calibrated to a target false discovery rate, so that
`fdr` has an interpretable, whole-tree error-rate meaning:

```{r message=FALSE}
trestruct( tree, fdr = 0.05 )
```

The [false discovery rate](false_discovery_rate.html) vignette explains what the rate
controls, the global test for any structure, and the effect of serial (heterochronous)
sampling.

### Subjective significance level

Supplying a `level` (without `fdr`) uses it instead as a fixed per-test significance.
This is a subjective clustering threshold rather than an error rate: raising it detects
more clusters but also increases the false positive rate.

```{r message=FALSE}
trestruct( tree, level = 0.05 )
```

The best value of `level` depends on your application. One way to choose it is to use
additional data associated with each sample, selecting the `level` that gives clusters
explaining the most variance in a variable of interest (e.g. using the cluster as a
factor in an ANOVA).

### CH index

Alternatively, in the absence of any additional data, the `treestructure` package
supports using the [CH index](https://en.wikipedia.org/wiki/Calinski–Harabasz_index)
to compare different `level`s. This statistic is based on the ratio of the
between-cluster and within-cluster variance of the time of each node
(distance from the root) and returns the `level` such that this ratio is maximized.
If you wish to use the CH index, pass `level = NULL` to `trestruct`, and
read documentation for the `levellb`, `levelub`, and `res` parameters.
