Semantically Rich I/O for the 'NeXML' Format

Provides access to phyloinformatic data in 'NeXML' format. The package should add new functionality to R such as the possibility to manipulate 'NeXML' objects in more various and refined way and compatibility with 'ape' objects.

DOI Build Status

  • Maintainer: Carl Boettiger
  • Authors: Carl Boettiger, Scott Chamberlain, Hilmar Lapp, Kseniia Shumelchyk, Rutger Vos
  • License: BSD-3
  • Issues: Bug reports, feature requests, and development discussion.

An extensive and rapidly growing collection of richly annotated phylogenetics data is now available in the NeXML format. NeXML relies on state-of-the-art data exchange technology to provide a format that can be both validated and extended, providing a data quality assurance and adaptability to the future that is lacking in other formats. See Vos et al 2012 for further details on the NeXML format.

How to cite

RNeXML has been published in the following article:

Although the published version of the article is paywalled, the source of the manuscript, and a much better rendered PDF, are included in this package (in the manuscripts folder). You can also find it freely available on arXiv.

Getting Started

The latest stable release of RNeXML is on CRAN, and can be installed with the usual install.packages("RNeXML") command. Some of the more specialized functionality described in the Vignettes (such as RDF manipulation) requires additional packages which can be installed using:

install.packages("RNeXML", deps=TRUE, repos=c("", ""))

which will also install the development version of the RNeXML package. For most common tasks such as shown here, those additional packages are not required. The development version of RNeXML is also available on Github. With the devtools package installed on your system, RNeXML can be installed using:


Read in a nexml file into the ape::phylo format:

f <- system.file("examples", "comp_analysis.xml", package="RNeXML")
nexml <- nexml_read(f)
tr <- get_trees(nexml) # or: as(nexml, "phylo")

Write an ape::phylo tree into the nexml format:

nexml_write(bird.orders, "test.xml")

A key feature of NeXML is the ability to formally validate the construction of the data file against the standard (the lack of such a feature in nexus files had lead to inconsistencies across different software platforms, and some files that cannot be read at all). While it is difficult to make an invalid NeXML file from RNeXML, it never hurts to validate just to be sure:

#> [1] TRUE

Extract metadata from the NeXML file:

birds <- nexml_read("test.xml")
#>     otu            label about xsi.type otus
#> 1  ou70 Struthioniformes #ou70       NA  os4
#> 2  ou71     Tinamiformes #ou71       NA  os4
#> 3  ou72      Craciformes #ou72       NA  os4
#> 4  ou73      Galliformes #ou73       NA  os4
#> 5  ou74     Anseriformes #ou74       NA  os4
#> 6  ou75    Turniciformes #ou75       NA  os4
#> 7  ou76       Piciformes #ou76       NA  os4
#> 8  ou77    Galbuliformes #ou77       NA  os4
#> 9  ou78   Bucerotiformes #ou78       NA  os4
#> 10 ou79      Upupiformes #ou79       NA  os4
#> 11 ou80    Trogoniformes #ou80       NA  os4
#> 12 ou81    Coraciiformes #ou81       NA  os4
#> 13 ou82      Coliiformes #ou82       NA  os4
#> 14 ou83     Cuculiformes #ou83       NA  os4
#> 15 ou84   Psittaciformes #ou84       NA  os4
#> 16 ou85      Apodiformes #ou85       NA  os4
#> 17 ou86   Trochiliformes #ou86       NA  os4
#> 18 ou87  Musophagiformes #ou87       NA  os4
#> 19 ou88     Strigiformes #ou88       NA  os4
#> 20 ou89    Columbiformes #ou89       NA  os4
#> 21 ou90       Gruiformes #ou90       NA  os4
#> 22 ou91    Ciconiiformes #ou91       NA  os4
#> 23 ou92    Passeriformes #ou92       NA  os4
#>   LiteralMeta                      property   datatype content
#> 1         m15                    dc:creator xsd:string        
#> 2        <NA>                          <NA>       <NA>    <NA>
#> 3         m17 dcterms:bibliographicCitation xsd:string    <NA>
#>       xsi.type ResourceMeta        rel
#> 1  LiteralMeta         <NA>       <NA>
#> 2 ResourceMeta          m16 cc:license
#> 3  LiteralMeta         <NA>       <NA>
#>                                                href
#> 1                                              <NA>
#> 2
#> 3                                              <NA>

Add basic additional metadata:

  nexml_write(bird.orders, file="meta_example.xml",
              title = "My test title",
              description = "A description of my test",
              creator = "Carl Boettiger <[email protected]>",
              publisher = "unpublished data",
              pubdate = "2012-04-01")
#> [1] "meta_example.xml"

By default, RNeXML adds certain metadata, including the NCBI taxon id numbers for all named taxa. This acts a check on the spelling and definitions of the taxa as well as providing a link to additional metadata about each taxonomic unit described in the dataset.

Advanced annotation

We can also add arbitrary metadata to a NeXML tree by define meta objects:

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

Advanced use requires specifying the namespace used. Metadata follows the RDFa conventions. Here we indicate the modification date using the prism vocabulary. This namespace is included by default, as it is used for some of the basic metadata shown in the previous example. We can see from this list:

#>                                              nex 
#>                      "
#>                                              xsi 
#>      "
#>                                              xml 
#>           "
#>                                             cdao 
#>        "
#>                                              xsd 
#>              "" 
#>                                               dc 
#>               "
#>                                          dcterms 
#>                      "
#>                                              ter 
#>                      "
#>                                            prism 
#> "
#>                                               cc 
#>                 "" 
#>                                             ncbi 
#>          "" 
#>                                               tc 
#>  ""

This next block defines a resource (link), described by the rel attribute as a homepage, a term in the foaf vocabulalry. Becuase foaf is not a default namespace, we will have to provide its URL in the full definition below.

website <- meta(href = "", 
                rel = "foaf:homepage")

Here we create a history node using the skos namespace. We can also add id values to any metadata element to make the element easier to reference externally:

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

For this kind of richer annotation, it is best to build up our NeXML object sequentially. Frist we will add bird.orders phylogeny to a new phylogenetic object, and then we will add the metadata elements created above to this object. Finally, we will write the object out as an XML file:

  birds <- add_trees(bird.orders)
  birds <- add_meta(meta = list(history, modified, website),
                    namespaces = c(skos = "",
                                   foaf = ""),
              file = "example.xml")
#> [1] "example.xml"

Taxonomic identifiers

Add taxonomic identifier metadata to the OTU elements:

nex <- add_trees(bird.orders)
nex <- taxize_nexml(nex)

Working with character data

NeXML also provides a standard exchange format for handling character data. The R platform is particularly popular in the context of phylogenetic comparative methods, which consider both a given phylogeny and a set of traits. NeXML provides an ideal tool for handling this metadata.

Extracting character data

We can load the library, parse the NeXML file and extract both the characters and the phylogeny.

nexml <- read.nexml(system.file("examples", "comp_analysis.xml", package="RNeXML"))
traits <- get_characters(nexml)
tree <- get_trees(nexml)

(Note that get_characters would return both discrete and continuous characters together in the same data.frame, but we use get_characters_list to get separate data.frames for the continuous characters block and the discrete characters block).

We can then fire up geiger and fit, say, a Brownian motion model the continuous data and a Markov transition matrix to the discrete states:

fitContinuous(tree, traits[1], ncores=1)
#> GEIGER-fitted comparative model of continuous data
#>  fitted 'BM' model parameters:
#>  sigsq = 1.166011
#>  z0 = 0.255591
#>  model summary:
#>  log-likelihood = -20.501183
#>  AIC = 45.002367
#>  AICc = 46.716652
#>  free parameters = 2
#> Convergence diagnostics:
#>  optimization iterations = 100
#>  failed iterations = 0
#>  frequency of best fit = 1.00
#>  object summary:
#>  'lik' -- likelihood function
#>  'bnd' -- bounds for likelihood search
#>  'res' -- optimization iteration summary
#>  'opt' -- maximum likelihood parameter estimates
fitDiscrete(tree, traits[2], ncores=1)
#> GEIGER-fitted comparative model of discrete data
#>  fitted Q matrix:
#>                 0           1
#>     0 -0.07308302  0.07308302
#>     1  0.07308302 -0.07308302
#>  model summary:
#>  log-likelihood = -4.574133
#>  AIC = 11.148266
#>  AICc = 11.648266
#>  free parameters = 1
#> Convergence diagnostics:
#>  optimization iterations = 100
#>  failed iterations = 0
#>  frequency of best fit = 1.00
#>  object summary:
#>  'lik' -- likelihood function
#>  'bnd' -- bounds for likelihood search
#>  'res' -- optimization iteration summary
#>  'opt' -- maximum likelihood parameter estimates

ropensci footer



For more fine-grained list of changes or to report a bug, consult


Releases will be numbered with the following semantic versioning format:


And constructed with the following guidelines:

  • Breaking backward compatibility bumps the major (and resets the minor and patch)
  • New additions without breaking backward compatibility bumps the minor (and resets the patch)
  • Bug fixes and misc changes bumps the patch
  • Following the RStudio convention, a .99 is appended after the patch number to indicate the development version on Github. Any version Coming from Github will now use the .99 extension, which will never appear in a version number for the package on CRAN.

For more information on SemVer, please visit


  • patch for compatibility with upcoming release of testthat


  • Bugfixes following release of new dplyr and new tidyr dependencies


  • Migrate Additional_repositories to new address for OmegaHat project.


  • get_metadata(), get_taxa() now return much richer data.frames instead of named vectors. This is potentially a non-backwards compatible change if scripts use the output of these functions as lists (#129). See updated metadata vignette. This introduces new dependencies dplyr and lazyeval.
  • more robust nexml_read() method for URLs, (#123)
  • Avoid assuming the namespace prefix nex for nexml elements (#51, #124, #126). Includes a fix server-side on the NeXML validator as well.
  • nexml_validate() points to the new validator. (#126)


  • Fix compatibilty issue with recent phytools release.


  • Upgrade tests to be compatible with newest testthat (0.10.0), bumps testthat dependency version up (#119) thanks @hadley


  • Add four new vignettes describing the use of various advanced features in the package: the use of SPARQL queries, advanced use of metadata features, an example of how to extend NeXML with simmap data as the use case, and documentation on the central S4 data structure used in the package.
  • Implements the use of Title Case in the package title, as requested (on several occassions) by the CRAN maintainers.


  • Update DESCRIPTION to provide a standard install.packages() compatible repository for rrdf, as per request from the CRAN team.


  • add URL and BugReports to Description. #103

  • for consistency with other add_ methods, the nexml object is now the last, not the first, argument to add_basic_meta. As this changes the function API, it could break code that does not explicitly name the arguments, so we release this as 2.0.0


Minor bugfix

  • Fixes typo that caused validator to fail when couldn't be reached


Less aggressive unit-tests

  • nexml_validate now returns NULL if the validation cannot be performed. Unit tests now consider either TRUE or NULL as acceptable.
  • Just skips the uuid unit test if uuid package is not available
  • Documented versioning practice in NEWS


Documentation and less agressive unit tests

  • Unit tests relying on the Figshare API are not run (without failing) if authentication to figshare server fails
  • Documentation updated to include examples for all functions


Initial Release

Reference manual

It appears you don't have a PDF plugin for this browser. You can click here to download the reference manual.


2.1.1 by Carl Boettiger, 2 months ago

Report a bug at

Browse source code at

Authors: Carl Boettiger [cre, aut] (<>), Scott Chamberlain [aut] (<>), Hilmar Lapp [aut] (<>), Kseniia Shumelchyk [aut], Rutger Vos [aut] (<>)

Documentation:   PDF Manual  

Task views: Phylogenetics, Especially Comparative Methods

BSD_3_clause + file LICENSE license

Imports XML, plyr, reshape2, httr, uuid, dplyr, lazyeval, tidyr, stringr, xml2

Depends on ape, methods

Suggests rdflib, geiger, phytools, knitr, rfigshare, knitcitations, testthat, phylobase, rmarkdown, xslt, taxize, covr

Imported by phylobase.

Suggested by rotl.

See at CRAN