--- title: "Introduction to taxodist" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Introduction to taxodist} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.align = "center" ) library(taxodist) if (is.null(taxobase$matrix)) { stop( "The installed taxobase object does not contain the reference matrix. ", "Rebuild data/taxobase.rda before building this vignette." ) } ``` ## Overview `taxodist` retrieves ordered taxonomic lineages from The Taxonomicon and uses them to compare named nodes in a classification hierarchy. The package provides functions for: - lineage retrieval; - most-recent-common-ancestor queries; - taxonomic hierarchy distances; - clade membership and filtering; - paths between hierarchy nodes; - pairwise distance matrices; - clustering and principal coordinates analysis; - session and persistent cache management. Inputs may represent species, genera, families, orders, named clades, or other nodes available in the source classification. ## What the distance represents Let \(L_A\) and \(L_B\) be the ordered lineages of two hierarchy nodes. Let \(h(A,B)\) be the depth of their most recent common ancestor, defined from their continuous common prefix. The distance is \[ d(A,B) = \begin{cases} 0, & L_A = L_B, \\ 1/h(A,B), & L_A \ne L_B. \end{cases} \] A deeper shared ancestor produces a smaller distance. Within a connected hierarchy, finite distances lie between zero and one. If two lineages have no shared root, the package returns an infinite distance. Missing lineages instead produce missing pairwise values in a distance matrix. The measure is an ultrametric within each connected hierarchy. Its mathematical properties and assumptions are discussed in: ```{r methodology-link, eval=FALSE} vignette("methodological-notes", package = "taxodist") ``` ## Distance and membership are different A descendant belongs to each clade represented among its ancestors. However, the descendant and ancestor remain distinct hierarchy nodes. For example, *Tyrannosaurus* is a member of *Dinosauria*, but the distance between the two nodes is positive: \[ d(\textit{Tyrannosaurus},\textit{Dinosauria}) = \frac{1}{\operatorname{depth}(\textit{Dinosauria})}. \] Use: - `taxo_distance()` to compare hierarchy nodes; - `is_member()` to test containment within a clade; - `taxo_path()` to inspect the complete ancestry path between nodes. The distance represents classification depth. It is not evolutionary time, genetic distance, morphological divergence, or phylogenetic branch length. ## Reproducible packaged examples The package includes `taxobase`, a reference object generated from The Taxonomicon. It allows documentation and examples to run without contacting an external service. ```{r taxobase} names(taxobase) taxobase$metadata ``` The metadata records the source, generation date, package version, and distance definition used to construct the object. ### Stored lineages ```{r stored-lineages} tail(taxobase$lineage_tyrannosaurus) tail(taxobase$lineage_homo) ``` Lineages are ordered from the root of the source classification to the queried node. ### Stored pairwise comparison ```{r stored-pairwise} taxobase$pairwise ``` A `taxodist_result` records: - the distance; - the MRCA and its depth; - the depth of each complete lineage; - the two queried names. ```{r result-structure} class(taxobase$pairwise) names(taxobase$pairwise) ``` ### Reference distance matrix ```{r reference-matrix} reference_matrix <- taxobase$matrix inherits(reference_matrix, "dist") attr(reference_matrix, "Size") head(attr(reference_matrix, "Labels")) round( as.matrix(reference_matrix)[1:6, 1:6], digits = 4 ) ``` A matrix returned by `distance_matrix()` is a standard R `dist` object. It is symmetric, has a zero diagonal, and can be supplied to functions accepting pairwise dissimilarities. ## Live lineage queries The following examples contact The Taxonomicon and are not evaluated while the vignette is built. ### Retrieving a lineage ```{r live-lineage, eval=FALSE} get_lineage("Tyrannosaurus") get_lineage("Drosophila melanogaster") ``` Numeric Taxonomicon identifiers can also be supplied directly: ```{r lineage-id, eval=FALSE} get_lineage("67263") ``` Using an identifier is useful when a name corresponds to more than one valid taxonomic entry. ### Computing a pairwise distance ```{r live-distance, eval=FALSE} result <- taxo_distance( "Tyrannosaurus", "Velociraptor" ) result result$distance result$mrca ``` ### Finding the MRCA ```{r live-mrca, eval=FALSE} mrca("Tyrannosaurus", "Velociraptor") mrca("Tyrannosaurus", "Triceratops") mrca("Tyrannosaurus", "Homo") ``` The returned MRCA depends on the classification currently provided by The Taxonomicon and may change following taxonomic revisions. ### Inspecting the path between nodes ```{r live-path, eval=FALSE} taxo_path( "Tyrannosaurus", "Triceratops" ) taxo_path( "Dinosauria", "Tyrannosaurus" ) ``` The path ascends from the first node to the MRCA and descends toward the second node. For an ancestor-descendant pair, the ancestor itself is the MRCA. ## Working with multiple taxa ### Constructing a distance matrix ```{r live-matrix, eval=FALSE} taxa <- c( "Tyrannosaurus", "Velociraptor", "Spinosaurus", "Allosaurus" ) mat <- distance_matrix( taxa, progress = TRUE ) mat ``` Lineages are retrieved once and cached for subsequent comparisons. ### Finding the closest candidates A stored example is available in `taxobase`: ```{r stored-closest} taxobase$closest ``` For a live query: ```{r live-closest, eval=FALSE} closest_relative( "Carnotaurus", c( "Aucasaurus", "Velociraptor", "Triceratops", "Brachiosaurus" ) ) ``` Candidates are sorted from smallest to largest distance. A missing candidate is retained with a missing distance. ### Focal distances ```{r live-focal, eval=FALSE} focal_distances( focal = "Tyrannosaurus", community = c( "Velociraptor", "Triceratops", "Spinosaurus" ) ) ``` This produces a table containing the candidate name, distance, MRCA, and MRCA depth. ## Clade operations ### Testing membership ```{r live-membership, eval=FALSE} is_member("Tyrannosaurus", "Dinosauria") is_member("Tyrannosaurus", "Theropoda") is_member("Tyrannosaurus", "Ornithischia") ``` Matching is case-insensitive, ignores surrounding whitespace, and requires the complete clade name rather than a partial substring. ### Filtering taxa The package data include a stored filtering example: ```{r stored-filter} taxobase$filter ``` A live operation can be performed with: ```{r live-filter, eval=FALSE} taxa <- c( "Tyrannosaurus", "Carnotaurus", "Triceratops", "Velociraptor", "Homo", "Drosophila" ) filter_clade(taxa, "Dinosauria") filter_clade(taxa, "Theropoda") ``` ### Shared clades and lineage comparison ```{r live-comparison, eval=FALSE} shared_clades( "Tyrannosaurus", "Triceratops" ) compare_lineages( "Carnotaurus", "Tyrannosaurus" ) ``` Shared ancestry is determined from the continuous common lineage prefix. A name repeated after the first divergence is not treated as a shared ancestor. ## Clustering, ordination, and visualization The following examples use a subset of the packaged matrix and therefore require no network access. ```{r analysis-matrix} labels <- attr(reference_matrix, "Labels")[1:8] example_matrix <- stats::as.dist( as.matrix(reference_matrix)[labels, labels] ) example_matrix ``` ### Hierarchical clustering ```{r clustering, fig.width=7, fig.height=5} clustering <- taxo_cluster( example_matrix, method = "average" ) plot( clustering, main = "Taxonomic hierarchy distance clustering", xlab = "", sub = "" ) ``` The result is a clustering dendrogram, not an independently inferred phylogenetic tree. ### Principal coordinates analysis ```{r ordination, fig.width=7, fig.height=5} ordination <- taxo_ordinate( example_matrix, k = 2 ) summary(ordination) plot( ordination, main = "Taxonomic hierarchy distance space" ) ``` The goodness-of-fit and eigenvalues should be examined before interpreting a low-dimensional representation. ### Heatmap ```{r heatmap, fig.width=7, fig.height=6} taxo_heatmap( example_matrix, main = "Taxonomic hierarchy distance matrix" ) ``` Additional statistical examples and interpretation are provided in: ```{r statistics-link, eval=FALSE} vignette("statistical-applications", package = "taxodist") ``` ## Name resolution and coverage Taxonomic names may be missing, ambiguous, redirected, or associated with non-biological homonyms. `taxo_search()` returns candidate Taxonomicon entries: ```{r live-search, eval=FALSE} taxo_search("Panthera") taxo_search("Bacteria") ``` When several valid biological entries exist, the package reports the available identifiers. A numeric identifier should be supplied when the intended taxonomic concept is known. Before calculating a large matrix, coverage can be checked explicitly: ```{r live-coverage, eval=FALSE} taxa <- c( "Tyrannosaurus", "Velociraptor", "Quercus", "Not_a_real_taxon" ) check_coverage(taxa) ``` Unresolved taxa generate missing pairwise distances. These values should be examined before clustering, ordination, or other methods requiring complete finite matrices. ## Cache management Taxonomicon identifiers and lineages are cached in memory during an R session. This avoids repeated requests for the same taxa. ```{r live-cache, eval=FALSE} cache_info() clear_cache() ``` The cache can also be saved and restored: ```{r persistent-cache, eval=FALSE} save_cache("taxodist-cache.rds") clear_cache() load_cache("taxodist-cache.rds") ``` Cache files preserve retrieved lineages across sessions. They should be regenerated when an analysis is intended to incorporate subsequent revisions of the source classification. ## Interpretation and reproducibility The numerical distance depends on the classification supplied by The Taxonomicon. Changes in lineage resolution or taxonomic concepts can alter MRCA depths and therefore alter distances. A reproducible analysis should record: - the `taxodist` version; - the retrieval or dataset-generation date; - the source classification; - numeric identifiers used to resolve ambiguous names; - missing or excluded taxa; - the distance definition; - downstream clustering or ordination settings. Saved caches and distance matrices can preserve the exact input used in an analysis. ## Data source and citation All retrieved lineage data originate from The Taxonomicon, based on *Systema Naturae 2000*. Formatted references for both the package and the data source are available with: ```{r citation, eval=FALSE} citation("taxodist") ``` Both the software and the underlying taxonomic source should be cited in published analyses.