--- title: "Exploring the backbone" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Exploring the backbone} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- `taxify()` reads a backbone in one direction, from a name to its accepted taxon. This article shows the functions that read it in the others: the synonyms of a taxon, the species of a genus, the ranks above a species, the taxon behind an ID, the parts of a name, and common names. It ends with a taxonomy tree of a species list. Installation is covered in [Get started](taxify.html). Every example reads the Catalogue of Life (COL); `backbone` names another. 1. **List** synonyms with `synonyms()`, and the taxa below a genus or family with `children()` and `downstream()`. 2. **Climb** to the ranks above a taxon with `upstream()` and `add_classification()`. 3. **Look up** IDs with `id2name()` and `taxify_ids()`, and the parts of a name with `parse_name()`. 4. **Translate** common names with `comm2sci()` and `sci2comm()`. 5. **Compare** a list with `lowest_common()` and `class2tree()`. ``` r library(taxify) ``` ## Synonyms A species list can hold old names for a taxon. `synonyms()` resolves each name to its accepted taxon and lists every synonym the backbone points to it: ``` r syn <- synonyms("Picea abies", backbone = "col", verbose = FALSE) nrow(syn) #> [1] 169 head(syn[, c("synonym", "authorship")]) #> synonym authorship #> 1 Abies abies (L.) Druce #> 2 Abies carpatica (Loudon) Ravenscr. #> 3 Abies cinerea Borkh. #> 4 Abies clambrasiliana Lavallée #> 5 Abies clanbrassiliana P.Lawson #> 6 Abies coerulescens K.Koch ``` The input can itself be a synonym: `synonyms("Pinus abies")` lists the same set, through the accepted *Picea abies*. ## Taxa below a genus or family To complete a checklist, the species of a genus are needed. `children()` lists the accepted species of a genus, or of a family: ``` r spruces <- children("Picea", backbone = "col", verbose = FALSE) nrow(spruces) #> [1] 42 head(spruces[, c("name", "authorship", "rank")]) #> name authorship rank #> 1 Picea abies (L.) H.Karst. SPECIES #> 2 Picea albertiana S.Br. SPECIES #> 3 Picea alcoquiana (H.J.Veitch ex Lindl.) Carrière SPECIES #> 4 Picea asperata Mast. SPECIES #> 5 Picea aurantiaca Mast. SPECIES #> 6 Picea austropanlanica Silba SPECIES ``` `downstream()` does the same from any higher taxon to any rank below it. The genera of the pine family: ``` r genera <- downstream("Pinaceae", backbone = "col", downto = "genus", verbose = FALSE) genera$name #> [1] "Abies" "Cathaya" "Cedrus" "Keteleeria" "Larix" #> [6] "Nothotsuga" "Picea" "Pinus" "Pseudolarix" "Pseudotsuga" #> [11] "Tsuga" ``` Both return accepted taxa only, and never the parent itself. A genus name used in two kingdoms, such as *Prunella*, is split with `kingdom`, as in `taxify()`. ## Ranks above a taxon Grouping species by family or order needs their classification. `upstream()` returns the classification of one taxon, one row per rank. A synonym or misspelling is resolved first: ``` r upstream("Pinus abies", backbone = "col", verbose = FALSE) #> input_name accepted_name rank name backbone #> 1 Pinus abies Picea abies kingdom Plantae col #> 2 Pinus abies Picea abies phylum Tracheophyta col #> 3 Pinus abies Picea abies class Pinopsida col #> 4 Pinus abies Picea abies order Pinales col #> 5 Pinus abies Picea abies family Pinaceae col #> 6 Pinus abies Picea abies genus Picea col ``` `to = "family"` returns only that rank. For a whole result, `add_classification()` adds kingdom, phylum, class and order as columns: ``` r res <- taxify(c("Picea abies", "Panthera leo"), backbone = "col", verbose = FALSE) cls <- add_classification(res, verbose = FALSE) cls[, c("input_name", "kingdom", "phylum", "class", "order", "family")] #> input_name kingdom phylum class order family #> 1 Picea abies Plantae Tracheophyta Pinopsida Pinales Pinaceae #> 2 Panthera leo Animalia Chordata Mammalia Carnivora Felidae #> Sources: COL 2026.09 | cite() for full citations ``` ## IDs A table that stores only backbone IDs can be read back with `id2name()`, which turns backbone IDs, such as those in the `taxon_id` and `accepted_id` columns, into names, ranks and accepted names: ``` r id2name(c("4HPZF", "KQB98"), backbone = "col", verbose = FALSE) #> id name authorship rank is_synonym accepted_name #> 1 4HPZF Picea abies (L.) H.Karst. SPECIES FALSE Picea abies #> 2 KQB98 Osphranter rufus (Desmarest, 1822) SPECIES FALSE Osphranter rufus #> family genus backbone #> 1 Pinaceae Picea col #> 2 Macropodidae Osphranter col ``` An ID is meaningful only within its backbone: GBIF keys, ITIS TSNs and WoRMS AphiaIDs are read against `"gbif"`, `"itis"` and `"worms"`. `taxify_ids()` lists every accepted taxon behind each matched name, one row per name and ID, with the pick marked: ``` r pa <- taxify("Pinus abies", backbone = "col", verbose = FALSE) ids <- taxify_ids(pa, verbose = FALSE) ids[, c("accepted_id", "accepted_name", "family", "is_pick")] #> accepted_id accepted_name family is_pick #> 1 4HPZF Picea abies Pinaceae TRUE #> 2 8K9Y Abies alba Pinaceae FALSE #> 3 6BRMR Cunninghamia lanceolata Cupressaceae FALSE #> 4 4HQ4F Picea polita Pinaceae FALSE ``` *Pinus abies* was used for four species. The pick is *Picea abies*; [How names are matched](fuzzy-matching.html#names-with-more-than-one-accepted-taxon) explains how it is chosen. ## The parts of a name Names from field sheets mix authors, qualifiers and hybrid signs into one string. `parse_name()` splits a name into its parts without matching it against a backbone: ``` r parse_name(c( "Quercus robur L.", "cf. Betula pendula Roth", "Abies alba subsp. borisii-regis (Mattf.) Kozuharov", "Mentha x piperita L." )) #> input_name genus specific_epithet #> 1 Quercus robur L. Quercus robur #> 2 cf. Betula pendula Roth Betula pendula #> 3 Abies alba subsp. borisii-regis (Mattf.) Kozuharov Abies alba #> 4 Mentha x piperita L. Mentha piperita #> infrasp_rank infrasp_epithet authorship qualifier is_hybrid #> 1 L. FALSE #> 2 Roth cf. FALSE #> 3 subsp. borisii-regis (Mattf.) Kozuharov FALSE #> 4 L. TRUE #> hybrid_type rank canonical #> 1 species Quercus robur #> 2 species Betula pendula #> 3 infraspecies Abies alba subsp. borisii-regis #> 4 nothospecies species Mentha piperita ``` `canonical` is the cleaned name that `taxify()` matches. `parse_name(code = "syntaxon")` parses the names of vegetation units, as shown in [Matching vegetation units](vegetation-units.html). ## Common names `sci2comm()` returns the common names of each taxon, from the vernacular names that GBIF, NCBI and the Open Tree of Life publish. `lang` takes two-letter language codes, and `name_rank` orders the names of a language by how many sources give them: ``` r cn <- sci2comm("Picea abies", lang = c("en", "de"), backbone = "col", verbose = FALSE) cn[cn$name_rank <= 2, c("common_name", "lang", "name_rank")] #> common_name lang name_rank #> 1 Gemeine Fichte de 1 #> 2 Gewöhnliche Fichte de 2 #> 5 Norway Spruce en 1 #> 6 White Spruce en 2 ``` `comm2sci()` goes the other way, with capitals ignored. A common name is often given to several taxa, so it returns every scientific name that carries it: ``` r sp <- comm2sci("Norway spruce", lang = "en", verbose = FALSE) nrow(sp) #> [1] 31 head(sp$accepted_name) #> [1] "Abies dicksonii" "Abies excelsa var. attenuata" #> [3] "Abies excelsa var. aurea" "Abies excelsa var. brevifolia" #> [5] "Abies excelsa var. eremita" "Abies excelsa var. finedonensis" ``` With `output = "result"`, the names are matched with `taxify()`, and `query_common` keeps the common name of each row: ``` r sp_res <- comm2sci("Norway spruce", lang = "en", output = "result", backbone = "col", verbose = FALSE) table(sp_res$accepted_name) #> #> Abies alba Abies sachalinensis var. nemorensis #> 2 1 #> Picea abies Picea abies var. abies #> 19 6 #> Picea abies var. acuminata #> 2 ``` Of the 31 names that carry "Norway spruce", 30 match COL, and 27 of those resolve to *Picea abies* or one of its varieties. The other three resolve to *Abies alba* and *Abies sachalinensis* var. *nemorensis*, so a common-name lookup gives candidates to check rather than one answer. `add_common_names()` attaches the first common name of each language as columns of a result. ## Comparing a list How closely the species of a list are related is the lowest rank they share, which `lowest_common()` returns: ``` r conifers <- c("Picea abies", "Pinus sylvestris", "Abies alba") lowest_common(conifers, backbone = "col", verbose = FALSE) #> rank name n_taxa #> 1 family Pinaceae 3 lowest_common(c("Picea abies", "Quercus robur"), backbone = "col", verbose = FALSE) #> rank name n_taxa #> 1 phylum Tracheophyta 2 ``` `class2tree()` builds a taxonomy tree from the classifications, as a Newick string, and as a `phylo` object when the ape package is installed: ``` r trees <- c(conifers, "Quercus robur", "Fagus sylvatica") tree <- class2tree(trees, backbone = "col", verbose = FALSE) tree$newick #> [1] "(((((((Picea_abies)Picea,(Pinus_sylvestris)Pinus,(Abies_alba)Abies)Pinaceae)Pinales)Pinopsida,((((Quercus_robur)Quercus,(Fagus_sylvatica)Fagus)Fagaceae)Fagales)Magnoliopsida)Tracheophyta)Plantae)root;" ``` The tree follows the ranks of the backbone's classification; it is not a phylogeny, and branch lengths carry no meaning. ## Where next - [How names are matched](fuzzy-matching.html): the forward direction, from a name to its accepted taxon. - [Requesting GBIF data for a species list](gbif-requests.html): `taxify_ids()` in a download of occurrence records.