---
title: "Handling Metadata in RNeXML"
author:
  - Carl Boettiger
  - Scott Chamberlain
  - Rutger Vos
  - Hilmar Lapp

output: html_vignette
---

<!--
%\VignetteEngine{knitr::rmarkdown}
%\VignetteIndexEntry{Handling Metadata in RNeXML}
-->


```{r compile-settings, include=FALSE}
library("methods")
library("knitr")
opts_chunk$set(tidy = FALSE, warning = FALSE, message = FALSE, 
               cache = FALSE, comment = NA, verbose = TRUE)
basename <- gsub(".Rmd", "", knitr:::knit_concord$get('infile')) 

```

## Writing NeXML metadata

The `add_basic_meta()` function takes as input an existing `nexml` object
(like the other `add_` functions, if none is provided it will create one), and at the time
of this writing any of the following
parameters: `title`, `description`, `creator`, `pubdate`, `rights`, `publisher`,
`citation`.  Other metadata elements and corresponding parameters may
be added in the future.

Load the packages and data:

```{r}
library('RNeXML')
data(bird.orders)
```

Create an `nexml` object for the phylogeny `bird.orders` and add appropriate metadata:

```{r}
birds <- add_trees(bird.orders)
birds <- add_basic_meta(
  title = "Phylogeny of the Orders of Birds From Sibley and Ahlquist",

  description = "This data set describes the phylogenetic relationships of the
     orders of birds as reported by Sibley and Ahlquist (1990). Sibley
     and Ahlquist inferred this phylogeny from an extensive number of
     DNA/DNA hybridization experiments. The ``tapestry'' reported by
     these two authors (more than 1000 species out of the ca. 9000
     extant bird species) generated a lot of debates.

     The present tree is based on the relationships among orders. The
     branch lengths were calculated from the values of Delta T50H as
     found in Sibley and Ahlquist (1990, fig. 353).",

  citation = "Sibley, C. G. and Ahlquist, J. E. (1990) Phylogeny and
     classification of birds: a study in molecular evolution. New
     Haven: Yale University Press.",

  creator = "Sibley, C. G. and Ahlquist, J. E.",
	nexml=birds)
```

Instead of a literal string, citations can also be provided in R's
`bibentry` type, which is the one in which R package citations are obtained:

```{r}
birds <- add_basic_meta(citation = citation("ape"), nexml = birds)
```

## Taxonomic identifiers

The `taxize_nexml()` function uses the R package `taxize` 
[@Chamberlain_2013] to check each taxon label against the NCBI database.
If a unique match is found, a metadata annotation is added to the taxon
providing the NCBI identification number to the taxonomic unit.


```{r message=FALSE, results='hide'}
birds <- taxize_nexml(birds, "NCBI")
```

If no match is found, the user is warned to check for possible typographic
errors in the taxonomic labels provided. If multiple matches are found,
the user will be prompted to choose between them.


## Custom metadata extensions

We can get a list of namespaces along with their prefixes from the `nexml` object: 

```{r}
prefixes <- get_namespaces(birds)
prefixes["dc"]
```

We create a `meta` element containing this annotation using the `meta` function:

```{r}
modified <- meta(property = "prism:modificationDate", content = "2013-10-04")
```

We can add this annotation to our existing `birds` NeXML file using the
`add_meta()` function.  Because we do not specify a level, it is added to
the root node, referring to the NeXML file as a whole.

```{r}
birds <- add_meta(modified, birds) 
```

The built-in vocabularies are just the tip of the iceberg of established
vocabularies. Here we add an annotation from the `skos` namespace which
describes the history of where the data comes from:

```{r}
history <- meta(property = "skos:historyNote",
  content = "Mapped from the bird.orders data in the ape package using RNeXML")
```

Because `skos` is not in the current namespace list, we add it with a
url when adding this meta element.  We also specify that this annotation
be placed at the level of the `trees` sub-node in the NeXML file.

```{r}
birds <- add_meta(history, 
                birds, 
                level = "trees",
                namespaces = c(skos = "http://www.w3.org/2004/02/skos/core#"))
```


For finer control of the level at which a `meta` element is added,
we will manipulate the `nexml` R object directly using S4 sub-setting,
as shown in the supplement.


Much richer metadata annotation is possible. Later we illustrate how
metadata annotation can be used to extend the base NeXML format to
represent new forms of data while maintaining compatibility with any
NeXML parser. The `RNeXML` package can be easily extended to support
helper functions such as `taxize_nexml` to add additional metadata
without imposing a large burden on the user.


## Reading NeXML metadata

A call to the `nexml` object prints some metadata summarizing the data structure: 

```{r }
birds
```

We can extract all metadata pertaining to the NeXML document as a whole
(annotations of the XML root node, `<nexml>`) with the command

```{r}
meta <- get_metadata(birds) 
```

This returns a named list of available metadata. We can see the kinds
of metadata recorded from the names (showing the first 4):

```{r}
names(meta)[1:4]
```

and can ask for a particular element using the standard list sub-setting
mechanism (i.e. either the name of an element or its numeric position),

```{r}
meta[["dc:title"]]
```

All metadata terms must belong to an explicit *namespace* or vocabulary
that allows a computer to interpret the term precisely. The prefix (before
the `:`) indicates to which vocabulary the term belongs, e.g. `dc` in
this case.  The `get_namespaces` function tells us the definition of
the vocabulary using a link:

```{r}
prefixes <- get_namespaces(birds)
prefixes["dc"]
```

Common metadata can be accessed with a few dedicated functions:

```{r get_citation}
get_citation(birds)
```


```{r get_taxa}
get_taxa(birds)
```

Which returns text from the otu element labels, typically used to define
taxonomic names, rather than text from explicit meta elements.

We can also access metadata at a specific level (or use `level=all`
to extract all meta elements in a list).  Here we show only the first
few results:

```{r} 
otu_meta <- get_metadata(birds, level="otu")
otu_meta[1:4]
```

