<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/what-are-these-birds-complement-occurrence-data-with-taxonomy-and-traits-information/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://ropensci.org/blog/2018/09/04/birds-taxo-traits/"> rOpenSci - open tools for open science</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>Thanks to the <a rel="nofollow" href="https://ropensci.org/blog/2018/08/21/birds-radolfzell/" target="_blank">second post of the series where we obtained data from<br>
eBird</a> we know<br>
what birds were observed in the county of Constance. Now, not all<br>
species' names mean a lot to me, and even if they did, there are a lot<br>
of them. In this post, we shall use rOpenSci's packages accessing<br>
taxonomy and trait data in order to summarize some characteristics of<br>
the birds' population of the county: armed with scientific and common<br>
names of birds, we have access to plenty of open data!</p>
<h3>Getting and filtering the occurrence data</h3>
<p>For more details about the following code, refer to the <a rel="nofollow" href="https://ropensci.org/blog/2018/08/21/birds-radolfzell/" target="_blank">previous post<br>
of the series</a>.<br>
The single difference is our adding a step to keep only data for the<br>
most recent years.</p>
<pre><code># polygon for filtering
landkreis_konstanz &lt;- osmdata::getbb(&quot;Landkreis Konstanz&quot;,
                             format_out = &quot;sf_polygon&quot;)
crs &lt;- sf::st_crs(landkreis_konstanz)

# get and filter data
f_out_ebd &lt;- &quot;ebird/ebd_lk_konstanz.txt&quot;

library(&quot;magrittr&quot;)

ebd &lt;- auk::read_ebd(f_out_ebd) %>%
  sf::st_as_sf(coords = c(&quot;longitude&quot;, &quot;latitude&quot;), 
                crs = crs) 

in_indices &lt;- sf::st_within(ebd, landkreis_konstanz)

ebd &lt;- dplyr::filter(ebd, lengths(in_indices) > 0)

ebd &lt;- as.data.frame(ebd)

ebd &lt;- dplyr::filter(ebd, approved, lubridate::year(observation_date) > 2010)

nrow(ebd)
</code></pre>
<pre><code>## [1] 8599
</code></pre>
<p>We will also need these two data.frames later: abundance by species, and<br>
dictionary of names.</p>
<pre><code>abundance &lt;- dplyr::count(ebd, scientific_name)

dico &lt;- unique(dplyr::select(ebd, scientific_name,
                             common_name))
</code></pre>
<h3>Getting taxonomic information</h3>
<p>In this section I would like to get an idea of how diverse the types of<br>
birds are in the County of Constance. I want to draw a phylogenetic tree<br>
of the local species, and for that, I'll first retrieve the<br>
classification for each species from<br>
<a rel="nofollow" href="https://www.ncbi.nlm.nih.gov/taxonomy" target="_blank">NCBI</a> using the <a rel="nofollow" href="https://github.com/ropensci/taxize" target="_blank"><code>taxize</code><br>
package</a> that &quot;allows users to<br>
search over many taxonomic data sources for species names (scientific<br>
and common) and download up and downstream taxonomic hierarchical<br>
information – among other things.â€�.</p>
<p>We first query *uid*'s and then use the <code>classification</code> function,<br>
instead of passing the species name directly to <code>classification</code>,<br>
because the IDs are unique whereas results for species names aren't.<br>
Rate limiting is thankfully managed by the package itself so we users do<br>
not need to worry about that.</p>
<pre><code>ids &lt;- taxize::get_uid(unique(ebd$scientific_name))
classif &lt;- taxize::classification(ids)

fs::dir_create(&quot;taxo&quot;)
save(classif, file = file.path(&quot;taxo&quot;, &quot;classif.RData&quot;))
</code></pre>
<p>There are 211 species, we get 211 elements in the classification<br>
(<code>sum(lengths(classif)==3)</code>), that is a list of data.frames:</p>
<pre><code>load(file.path(&quot;taxo&quot;, &quot;classif.RData&quot;))

str(classif[[1]])
</code></pre>
<pre><code>## 'data.frame':    31 obs. of  3 variables:
##  $ name: chr  &quot;cellular organisms&quot; &quot;Eukaryota&quot; &quot;Opisthokonta&quot; &quot;Metazoa&quot; ...
##  $ rank: chr  &quot;no rank&quot; &quot;superkingdom&quot; &quot;no rank&quot; &quot;kingdom&quot; ...
##  $ id  : chr  &quot;131567&quot; &quot;2759&quot; &quot;33154&quot; &quot;33208&quot; ...
</code></pre>
<p>Now, we'll represent the whole taxonomy as a tree, using the handy<br>
<code>taxize::class2tree</code> function and the great <a rel="nofollow" href="https://guangchuangyu.github.io/software/ggtree/" target="_blank"><code>ggtree</code> package by<br>
Guangchuang Yu</a>.</p>
<pre><code>tree &lt;- taxize::class2tree(classif)
</code></pre>
<pre><code>library(&quot;ggplot2&quot;)
ggtree::ggtree(tree$phylo) +
    ggtree::geom_tiplab(aes(), size = 2, vjust=0.25) +
  xlim(0, 150)
</code></pre>
<p><img alt="labelled tree of all
species" src="https://i0.wp.com/ropensci.org/img/blog-images/2018-09-04-birds-taxo-traits/firsttree-1.png?w=456&ssl=1" data-recalc-dims="1"></p>
<p>This tree isâ€¦ unreadable. But at this point, it's worth remembering that<br>
we got here using three <code>taxize</code> functions only: <code>taxize::get_uid</code>,<br>
<code>taxize::classification</code> and <code>taxize::class2tree</code>. What a smooth<br>
workflow!</p>
<p>We'll now concentrate on highlighting <em>orders</em>, inspired by <a rel="nofollow" href="https://rgriff23.github.io/2017/05/11/primate-phylogeny-ggtree.html" target="_blank">this blog<br>
post</a>.</p>
<p>There are 18 orders and I do not intend to add the highlighting command<br>
for each of them by hand! I'll streamline the process, starting by<br>
automatically extracting the node ID of each order. The solution below<br>
might be a little over-complicated, so R taxonomy experts, please chime<br>
in! I transformed the tree <code>phylo</code> object to a <code>phylo4</code> from the<br>
<a rel="nofollow" href="https://github.com/fmichonneau/phylobase" target="_blank"><code>phylobase</code> package</a><br>
maintained by FranÃ§ois Michonneau, in order to easily retrieve all<br>
ancestor nodes for any group of species. Within an order, the order node<br>
ID is the highest common node ID.</p>
<pre><code>p4 &lt;- phylobase::phylo4(tree$phylo)

# helper to translate labels
translate &lt;- function(scientific_name){
  if(scientific_name %in% dico$scientific_name){
    dico$common_name[dico$scientific_name == scientific_name]
  }else{
    scientific_name
  }
}


find_order_node_id &lt;- function(order, p4){
  order_members &lt;- as.character(tree$classification$species[tree$classification$order == order])
  nodes &lt;- phylobase::ancestors(p4, order_members, type = &quot;ALL&quot;)
  # the ID is the higher common node IDs
  nodes &lt;- purrr::map(nodes, as.numeric)
  
  if(length(order_members) > 1){
    id &lt;- max(Reduce(intersect, nodes))
  }else{
    id &lt;- min(unlist(nodes))
  }
  
  common_names &lt;- purrr::map_chr(order_members, translate)
  
  species &lt;-  stringr::str_wrap(toString(common_names),width = 50)
  
  tibble::tibble(id = id,
                 order = order,
                 size = length(order_members),
                 species = species)
  
}

orders &lt;- purrr::map_df(unique(tree$classification$order),
                        find_order_node_id,
                        p4)

str(orders)
</code></pre>
<pre><code>## Classes 'tbl_df', 'tbl' and 'data.frame':    18 obs. of  4 variables:
##  $ id     : num  237 238 235 239 231 10 228 226 224 222 ...
##  $ order  : Factor w/ 18 levels &quot;Anseriformes&quot;,..: 3 12 13 1 5 4 15 11 16 17 ...
##  $ size   : int  32 86 9 35 5 1 7 6 5 3 ...
##  $ species: chr  &quot;Black-headed Gull, Common Tern, Northern Lapwing,\nYellow-legged Gull, Common Sandpiper, Eurasian\nCurlew, Mew &quot;| __truncated__ &quot;Carrion Crow, Eurasian Magpie, House Sparrow,\nShort-toed Treecreeper, Eurasian Blackbird,\nEuropean Greenfinch&quot;| __truncated__ &quot;Gray Heron, Great Cormorant, Great Egret, Eurasian\nSpoonbill, Purple Heron, Cattle Egret, Little\nBittern, Lit&quot;| __truncated__ &quot;Mallard, Mute Swan, Common Goldeneye, Common\nMerganser, Common Pochard, Ferruginous Duck,\nGreen-winged Teal, &quot;| __truncated__ ...
</code></pre>
<p>For each order, I'll get a silhouette from Phylopic using <a rel="nofollow" href="https://github.com/sckott/rphylopic" target="_blank">Scott<br>
Chamberlain's <code>rphylopic</code> package</a>.</p>
<pre><code>get_results &lt;- function(name){
  
  id &lt;- rphylopic::name_search(name)
  rphylopic::name_images(id$canonicalName[1,1])
}

get_pic &lt;- function(order, classification){
  message(order)
  
  # shortcurt for flamingos
  if(order == &quot;Phoenicopteriformes&quot;){
    return(tibble::tibble(pic_id = &quot;28473411-c079-4654-bbb7-34a5615bb414&quot;,
                          order = &quot;Phoenicopteriformes&quot;))
  }
  
  classification &lt;- classification[classification$order == order,]
  
  results &lt;- get_results(order)
  
  if (length(results$same) > 0){
    # best case
    pic_id &lt;- results$`same`[[1]]$`uid`
  }else{
    # take the most common species
    # and get any pic of it
    results &lt;- get_results(classification$species[
      classification$n == max(classification$n, na.rm=TRUE)
    ][1])
    results &lt;- purrr::keep(results, function(x) length(x) > 0)
    results &lt;- unlist(results)
    results &lt;- results[length(results)]
    pic_id &lt;- as.character(results)
  }
  
  tibble::tibble(pic_id = pic_id,
                 order = order)
}


library(&quot;magrittr&quot;)
classification &lt;- tree$classification %>%
  dplyr::mutate(species = as.character(species)) %>%
  dplyr::left_join(abundance,
                   by = c(&quot;species&quot; = &quot;scientific_name&quot;))

ids &lt;- purrr::map_df(orders$order, get_pic,          classification)
save(ids, file = file.path(&quot;taxo&quot;, &quot;ids.RData&quot;))
</code></pre>
<p>It is rather tricky to automatically get pics from Phylopic since you<br>
might not get one for the order itself, maybe one for the subtaxon<br>
instead, etc, so we made decisions blindly in the script above. In real<br>
life one might prefer selecting IDs by hand.</p>
<p>Now, we can highlight each order! One could add silhouettes <a rel="nofollow" href="https://guangchuangyu.github.io/2018/03/annotating-phylogenetic-tree-with-images-using-ggtree-and-ggimage/" target="_blank">to the tree<br>
itself with<br>
<code>ggtree</code></a><br>
but I'll add them on the side instead.</p>
<pre><code># Get pics ids
load(file.path(&quot;taxo&quot;, &quot;ids.RData&quot;))

# Plot basic tree
p &lt;- ggtree::ggtree(tree$phylo) 

# Sort the orders by node id
orders &lt;- dplyr::arrange(orders, - id)

# Helper to plot one order
plot_order &lt;- function(order, orders,
                       ids, p){
                       
  # Get index
  i &lt;- which(orders$order == order)
  
  # From image ID get image itself 
  # and image metadata (copyright &amp;co)
  img_id &lt;- ids$pic_id[ids$order == order]
  img &lt;- rphylopic::image_data(img_id, 512)
  img_info &lt;- rphylopic::image_get(img_id,
                                   options = c(&quot;credit&quot;,
                                               &quot;licenseURL&quot;))
  
  if(is.null(img_info$credit)){
    img_info$credit &lt;- &quot;&quot;
  }
  
  # Now, plot!
  p +
  # Highlight the order
  ggtree::geom_hilight(node = orders$id[i],
                       fill = &quot;salmon&quot;) +
  # Order name as title
  ggtitle(orders$order[i])+
  xlim(0, 150) +
  ylim(0, 250) +
  # Add species names on the side
  annotate(&quot;text&quot;, x = 110,
           y = 200, label = orders$species[i],
           size = 4) +
  # Credit at the bottom
  annotate(&quot;text&quot;, x = 110,
           y = 0,
           size = 2,
          label = glue::glue(&quot;Silhouette: {img_info$credit}\n{img_info$licenseURL}&quot;))
  
  # Save a first time
  filepath &lt;- file.path(&quot;taxo&quot;, glue::glue(&quot;p{i}.png&quot;))
  ggsave(filepath, width = 7, height = 7)
  
  # Add silhouette via magick
  silhouette &lt;- magick::image_read(img[[1]])
  magick::image_read(filepath) %>%
    magick::image_composite(silhouette,
                            offset = &quot;+1300+1400&quot;) %>%
    magick::image_write(filepath)
  
}

# Create aaall plots
  
purrr::walk(orders$order, plot_order,
            orders, ids, p)

</code></pre>
<p>Once we have created all these PNGs, we can join them into a gif using<br>
<a rel="nofollow" href="https://ropensci.org/technotes/2018/07/23/gifski-release/" target="_blank">Jeroen Ooms'<br>
<code>gifski</code></a>.</p>
<pre><code>png_files &lt;- fs::dir_ls(&quot;taxo&quot;, regexp = &quot;[.]png$&quot;)

gifski::gifski(png_files = png_files,
               gif_file = file.path(&quot;2018-09-04-birds-taxo-traits_files&quot;,
                                    &quot;figure-markdown_github&quot;, &quot;taxo.gif&quot;),
               delay = 3,
               width = 500, height = 500,
               progress = FALSE)
</code></pre>
<pre><code>## [1] &quot;/img/blog-images/2018-09-04-birds-taxo-traits/taxo.gif&quot;
</code></pre>
<pre><code>knitr::include_graphics(file.path(&quot;2018-09-04-birds-taxo-traits_files&quot;,
                                    &quot;figure-markdown_github&quot;, &quot;taxo.gif&quot;)) 
</code></pre>
<p><img alt="animated tree with species names and order
silhouette" src="https://i0.wp.com/ropensci.org/img/blog-images/2018-09-04-birds-taxo-traits/taxo.gif?w=456&ssl=1" data-recalc-dims="1"></p>
<p>This gif shows many species names and<br>
<a rel="nofollow" href="https://en.wikipedia.org/wiki/Category:Bird_orders" target="_blank">orders</a> giving us a<br>
feeling for what we might encounter in the county of Constance, but it<br>
lacks quantitative information about the species. It'd be interesting to<br>
create trees such as the ones of the <a rel="nofollow" href="https://github.com/grunwaldlab/metacoder" target="_blank"><code>metacoder</code><br>
package</a> to reflect abundance,<br>
possibly depending on the very local area (distance to watery area) or<br>
season, potentially using the <code>taxize::downstream</code> function to get all<br>
families in each order, even families not present in our occurrence<br>
dataset. This idea is beyond the scope of this post. What <em>is</em> in scope,<br>
now, is trying to get trait information for the species.</p>
<h3>Getting trait information</h3>
<p>In ecology, <em>traits</em> are characteristics of organisms such as habitat,<br>
body size, threats, etc. It's a whole bunch of data you can get for free<br>
based on species scientific names, from different data providers. The<br>
<a rel="nofollow" href="https://github.com/ropensci/traits" target="_blank"><code>traits</code> package</a>, part of the<br>
rOpenSci's suite, is an interface to various sources of traits data. In<br>
this section, we shall use data from BirdLife International: habitat and<br>
threats.</p>
<p>The different functions of <code>traits</code> have prefixes indicating with which<br>
data source they interact. Here we shall use <code>traits::birdlife_habitat</code><br>
and <code>traits::birdlife_threats</code>. To get access to the data available for<br>
each species, we first need to get its IUCN ID using the <a rel="nofollow" href="https://github.com/ropensci/taxize" target="_blank"><code>taxize</code><br>
package</a> (or the <a rel="nofollow" href="https://github.com/ropensci/rredlist" target="_blank"><code>rredlist</code><br>
package</a> that it wraps)</p>
<pre><code>species &lt;-  unique(ebd$scientific_name)

get_info &lt;- function(species){
  message(species)
  Sys.sleep(1)
  iucn_id &lt;- taxize::iucn_id(species)
  if(!is.na(iucn_id)){
    habitat &lt;- traits::birdlife_habitat(iucn_id)
    threats &lt;- traits::birdlife_threats(iucn_id)
  }else{
    habitat &lt;- NULL
    threats &lt;- NULL
  }
 
  
  list(habitat = habitat,
       threats = threats)
}

species_info &lt;- purrr::map(species,
                           get_info)

names(species_info) &lt;- species
save(species_info, file = file.path(&quot;taxo&quot;, &quot;species_info.RData&quot;))
</code></pre>
<p>The script above isn't the smartest since it doesn't retain information<br>
about the species names. Not too bad here because I want to get a<br>
general idea of birds' habitats and threats over the county.</p>
<pre><code>habitat &lt;- purrr::map_df(species_info, &quot;habitat&quot;)
</code></pre>
<p>Out of 211, 203 are represented in this dataset.</p>
<pre><code>library(&quot;ggplot2&quot;)

habitat %>%
  janitor::clean_names() %>%
  dplyr::group_by(id) %>%
  dplyr::mutate(ok = all(c(&quot;breeding&quot;, &quot;non-breeding&quot;) %in% occurrence)) %>%
  dplyr::ungroup() %>%
  dplyr::filter(ok, importance == &quot;major&quot;) %>%
  dplyr::mutate(habitat = dplyr::case_when(stringr::str_detect(habitat_level_1,
                                                               &quot;Marine&quot;) ~ &quot;Marine&quot;,
                                           stringr::str_detect(habitat_level_1,
                                                               &quot;Rocky&quot;) ~ &quot;Rocky&quot;,
                                           TRUE  ~ habitat_level_1)) %>%
  ggplot() +
  geom_bar(aes(occurrence, fill = habitat),
           position = &quot;fill&quot;) +
  # palette recommended in https://github.com/clauswilke/colorblindr
  # for people with color-vision deficiency
  colorblindr::scale_fill_OkabeIto() +
  theme(legend.position = &quot;bottom&quot;) +
  hrbrthemes::theme_ipsum(base_size = 12, 
                          axis_title_size = 12,
                          axis_text_size = 12) +
  ggtitle(&quot;Habitats of birds from the county of Constance&quot;,
          subtitle = &quot;For birds with habitats data only for the breeding and non-breeding seasons&quot;) +
  ylab(&quot;Proportion&quot;) +
  xlab(&quot;Season of occurrence&quot;)
</code></pre>
<p><img alt="" src="https://i1.wp.com/ropensci.org/img/blog-images/2018-09-04-birds-taxo-traits/unnamed-chunk-9-1.png?w=456&ssl=1" data-recalc-dims="1"></p>
<p>It seems that the birds present in the County of Constance might have<br>
different distributions depending on the breeding/non-breeding season.<br>
It'd be interesting to look at in the occurrence data, since <code>auk</code><br>
allows zero-filling.</p>
<p>Let's have a look at threats data.</p>
<pre><code>threats &lt;- purrr::map_df(species_info, &quot;threats&quot;)
str(threats)
</code></pre>
<pre><code>## 'data.frame':    414 obs. of  8 variables:
##  $ id      : int  22696993 22696993 22696993 22696993 22696993 22696993 22696993 22696993 103888106 103888106 ...
##  $ threat1 : chr  &quot;Agriculture &amp; aquaculture&quot; &quot;Biological resource use&quot; &quot;Biological resource use&quot; &quot;Biological resource use&quot; ...
##  $ threat2 : chr  &quot;Annual &amp; perennial non-timber crops&quot; &quot;Hunting &amp; trapping terrestrial animals&quot; &quot;Hunting &amp; trapping terrestrial animals&quot; &quot;Logging &amp; wood harvesting&quot; ...
##  $ stresses: chr  &quot;Ecosystem degradation, Ecosystem conversion&quot; &quot;Species mortality&quot; &quot;Species mortality&quot; &quot;Species disturbance, Ecosystem degradation&quot; ...
##  $ timing  : chr  &quot;Agriculture &amp; aquaculture&quot; &quot;Biological resource use&quot; &quot;Biological resource use&quot; &quot;Biological resource use&quot; ...
##  $ scope   : chr  &quot;Annual &amp; perennial non-timber crops&quot; &quot;Hunting &amp; trapping terrestrial animals&quot; &quot;Hunting &amp; trapping terrestrial animals&quot; &quot;Logging &amp; wood harvesting&quot; ...
##  $ severity: chr  &quot;Ongoing&quot; &quot;Ongoing&quot; &quot;Past, Likely to Return&quot; &quot;Ongoing&quot; ...
##  $ impact  : chr  &quot;Ongoing&quot; &quot;Ongoing&quot; &quot;Past, Likely to Return&quot; &quot;Ongoing&quot; ...
</code></pre>
<p>As you can see, it is a depressing dataset since most threats are<br>
human-made, but such information can help conservation! Instead of<br>
diving into the fate of particular species, let's get a general picture.<br>
There are 211 species, for 68 we get an entry in the threats data. What<br>
are the most common threats for them, now and in the future?</p>
<pre><code>dplyr::filter(threats, severity %in% c(&quot;Future&quot;, &quot;Ongoing&quot;)) %>%
  dplyr::select(id, threat2, threat1) %>%
  dplyr::rename(threat_category = threat1) %>%
  dplyr::rename(threat_subcategory = threat2) %>%
  unique() %>%
  dplyr::count(threat_category, threat_subcategory) %>%
  dplyr::arrange(-n) %>%
  head(n = 5) %>%
  knitr::kable()
</code></pre>
<table>
<thead>
<tr>
<th align="left">threat_category</th>
<th align="left">threat_subcategory</th>
<th align="right">n</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">Biological resource use</td>
<td align="left">Hunting &amp; trapping terrestrial animals</td>
<td align="right">25</td>
</tr>
<tr>
<td align="left">Climate change &amp; severe weather</td>
<td align="left">Habitat shifting &amp; alteration</td>
<td align="right">24</td>
</tr>
<tr>
<td align="left">Energy production &amp; mining</td>
<td align="left">Renewable energy</td>
<td align="right">16</td>
</tr>
<tr>
<td align="left">Natural system modifications</td>
<td align="left">Dams &amp; water management/use</td>
<td align="right">14</td>
</tr>
<tr>
<td align="left">Pollution</td>
<td align="left">Agricultural &amp; forestry effluents</td>
<td align="right">14</td>
</tr>
</tbody>
</table>
<p>It's quite similar to the ranking in this post on <a rel="nofollow" href="https://www.birdlife.org/worldwide/news/top-five-threats-birds-may-surprise-you" target="_blank">BirdLife's<br>
website</a>:<br>
industrial farming, logging, invasive species, hunting and trapping,<br>
climate change. Note that these threats have been summarized by species,<br>
not by species and location, so this data doesn't tell us much about the<br>
state of each species in the County of Constance. If we wanted to<br>
characterize the County a bit more via the use of open data, we could<br>
use e.g. <a rel="nofollow" href="https://ropensci.github.io/osmdata/" target="_blank"><code>osmdata</code></a> to get<br>
land-use information via OpenStreetMap: instead of bird hides/blinds as<br>
in the first post we could get elements related to agriculture for<br>
instance.</p>
<h3>Conclusion</h3>
<h4>Characterizing the local birds population</h4>
<p>From occurrence data we got names of species observed at least once in<br>
the area over the last year. Using taxonomy data to classify them we<br>
were able to see quite a few birds orders are represented, and we were<br>
able to visualize corresponding silhouettes. Traits data is general and<br>
doesn't give information about the local context of birds in the County<br>
of Constance, however it could be coupled with more local data:<br>
localization of observations, and open geographical data. All the<br>
mentioned data sources are available for free, and can be obtained using<br>
R packages, cf <a rel="nofollow" href="https://ropensci.org/blog/2018/08/14/where-to-bird/" target="_blank">the<br>
first</a> and<br>
<a rel="nofollow" href="https://ropensci.org/blog/2018/08/21/birds-radolfzell/" target="_blank">second</a> post of<br>
the series.</p>
<h4>Taxonomy and traits data in R</h4>
<p>There are many R packages supporting your taxonomy work! In particular,<br>
within the rOpenSci suite <code>taxize</code> that we used here allows to get<br>
taxonomy information from many sources and <a rel="nofollow" href="https://github.com/ropensci/taxize-book" target="_blank">is the topic of a WIP online<br>
book</a>, while<br>
<a rel="nofollow" href="https://github.com/ropensci/taxa" target="_blank"><code>taxa</code></a>, maintained by Zachary<br>
Foster, defines taxonomy classes for R. rOpenSci maintains a task view<br>
of taxonomy packages <a rel="nofollow" href="https://github.com/ropensci/taxonomy" target="_blank">here</a>, part<br>
of which <a rel="nofollow" href="https://ropensci.org/blog/2017/07/27/taxonomy-suite/" target="_blank">form the rOpenSci taxonomy<br>
suite</a>.</p>
<p>Related to taxonomy are phylogenetics. The <a rel="nofollow" href="https://github.com/GuangchuangYu/treeio" target="_blank"><code>treeio</code><br>
package</a> by Guangchuang Yu<br>
provides base classes and functions for phylogenetic tree input and<br>
output and was onboarded. Guangchuang Yu's other packages such as<br>
<code>ggtree</code> and <code>tidytree</code> are also of interest for manipulating and<br>
visualizing trees. More generally, the <a rel="nofollow" href="https://cran.r-project.org/web/views/Phylogenetics.html" target="_blank">Phylogenetics CRAN task<br>
view</a> provides<br>
a sorted useful list of packages.</p>
<p>Based on species' names, one can also get traits data using the <code>traits</code><br>
package as we did in this post. Also of interest is the rOpenSci's<br>
<a rel="nofollow" href="https://github.com/ropensci/originr" target="_blank"><code>originr</code> package</a> providing<br>
different datasets about invasive and alien species.</p>
<p>Explore more of our packages suite, including and beyond the taxonomy<br>
and traits category, <a rel="nofollow" href="https://ropensci.org/packages/" target="_blank">here</a>.</p>
<h4>More birding soon!</h4>
<p>Stay tuned for the next and last post in this series, about querying the<br>
scientific literature and scientific open data for the bird species<br>
occurring in the county! In the meantime, happy birding!</p>
	<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://ropensci.org/blog/2018/09/04/birds-taxo-traits/"> rOpenSci - open tools for open science</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a rel="nofollow" href="https://www.r-project.org/" title="The R Project for Statistical Computing">R</a> news and <a rel="nofollow" href="https://www.r-bloggers.com/search/tutorial" title="R tutorials">tutorials</a> on topics such as: <a rel="nofollow" href="https://www.r-bloggers.com/search/data%20science" title="Data science">Data science</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data" title="Big Data">Big Data, <a rel="nofollow" href="https://www.r-users.com/" title="R jobs">R jobs</a>, visualization (<a rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2" title="ggplot and ggplot2 tutorials">ggplot2</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/boxplot" title="Boxplots using lattice and ggplot2 tutorials">Boxplots</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/map" title="Maps and gis">maps</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/animation" title="Animation in R">animation</a>), programming (<a rel="nofollow" href="https://www.r-bloggers.com/search/RStudio" title="RStudio IDE for R">RStudio</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/sweave" title="Sweave and literate programming">Sweave</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX" title="LaTeX in R">LaTeX</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/SQL" title="SQL and databases">SQL</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/eclipse" title="Eclipse IDE for R">Eclipse</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/git" title="git and github, Version Control System">git</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/hadoop" title="Large data in R using Hadoop">hadoop</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping" title="Web Scraping of google, facebook, yahoo, twitter and more using R">Web Scraping</a>) statistics (<a rel="nofollow" href="https://www.r-bloggers.com/search/regression" title="Regressions and ANOVA analysis tutorials">regression</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/PCA" title="principal component analysis tutorial">PCA</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/time+series" title="Time series">time series</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/trading" title="finance trading">trading</a>) and more...
<img width="1" alt="" src="http://feeds.feedburner.com/~r/RBloggers/~4/yYSoNwosQZg" height="1"></a></div>