Skip to contents

Introduction

This tutorial has been created to walk you through gathering common data from the IUCN Red List API. In Part 1, we will stay completely within the API by getting a list of species’ assessments directly from the taxon endpoint. In Part 2, we will show you how to import your own list of species’ names and perform the same data gathering steps.

Part 1 - Gather habitats & threats for the felidae

First, you’ll want to load the package into your R session and then initialise a connection to the Red List API. Initialising a connection will require you to have a valid API token. If you don’t already have one, you can sign up for one here.

library(iucnredlist)
api <- init_api("your_api_token")

We now need to gather a list of all (latest) assessments whose species belong to the family felidae:

felidae <- assessments_by_taxonomy(api, level = "family", name = "felidae", latest = TRUE)

# A tibble: 52 × 7
   sis_taxon_id assessment_id latest year_published scopes_description_en scopes_code url                                              
          <int>         <int> <lgl>  <chr>          <chr>                 <chr>       <chr>                                            
 1        11638       3299247 TRUE   2010           Mediterranean         4           https://www.iucnredlist.org/species/11638/3299247
 2        12519       3350985 TRUE   2010           Mediterranean         4           https://www.iucnredlist.org/species/12519/3350985
 3        15951       5325996 TRUE   2010           Mediterranean         4           https://www.iucnredlist.org/species/15951/5325996
 4        15954       5328595 TRUE   2010           Mediterranean         4           https://www.iucnredlist.org/species/15954/5328595
 5        15955       5330476 TRUE   2010           Mediterranean         4           https://www.iucnredlist.org/species/15955/5330476
 6         3847      10121483 TRUE   2010           Mediterranean         4           https://www.iucnredlist.org/species/3847/10121483
 7         8540      12915840 TRUE   2010           Mediterranean         4           https://www.iucnredlist.org/species/8540/12915840
 8         8540      12916263 TRUE   2007           Europe                2           https://www.iucnredlist.org/species/8540/12916263
 9         8541      12916598 TRUE   2010           Mediterranean         4           https://www.iucnredlist.org/species/8541/12916598
10          219      13034035 TRUE   2010           Mediterranean         4           https://www.iucnredlist.org/species/219/13034035 
# ℹ 42 more rows
# ℹ Use `print(n = ...)` to see more rows

As our aim is to gather all habitats and threats coded against these assessments, we must now iterate over each unique assessment ID in the above tibble to get that data. Helpfully, there’s a function available to do just that:

# Pass assessment IDs into the assessment_data_many() function
felidae_full <- assessment_data_many(api, assessment_ids = felidae$assessment_id)

After this runs, we will how have full assessment data for all 50 unique assessment IDs (as of time of publication). From here, we can extract the data we are interested in with:

habitats <- extract_element(felidae_full, "habitats")

The extract_element() function is super helpful. It returns a tidy dataframe of the element you’re interested; a row for each unique element and assessment ID for all of the assessments you gathered full assessment data for:

habitats

# A tibble: 452 × 7
   index    assessment_id majorImportance season suitability description                                                               code 
   <chr>    <chr>         <chr>           <chr>  <chr>       <chr>                                                                     <chr>
 1 habitats 3299247       NA              NA     Suitable    Wetlands (inland) - Shrub Dominated Wetlands                              5_3  
 2 habitats 3299247       NA              NA     Suitable    Grassland - Subtropical/Tropical High Altitude                            4_7  
 3 habitats 3299247       NA              NA     Suitable    Wetlands (inland) - Permanent Rivers/Streams/Creeks (includes waterfalls) 5_1  
 4 habitats 3299247       NA              NA     Suitable    Forest - Subtropical/Tropical Dry                                         1_5  
 5 habitats 3299247       NA              NA     Suitable    Savanna - Dry                                                             2_1  
 6 habitats 3299247       NA              NA     Suitable    Grassland - Subtropical/Tropical Dry                                      4_5  
 7 habitats 3299247       NA              NA     Suitable    Grassland - Subtropical/Tropical Seasonally Wet/Flooded                   4_6  
 8 habitats 3350985       NA              NA     Suitable    Shrubland - Boreal                                                        3_3  
 9 habitats 3350985       NA              NA     Suitable    Shrubland - Subtropical/Tropical Dry                                      3_5  
10 habitats 3350985       NA              NA     Suitable    Shrubland - Temperate                                                     3_4  
# ℹ 442 more rows
# ℹ Use `print(n = ...)` to see more rows

You can now do the same for threats:

threats <- extract_element(felidae_full, "threats")

threats

# A tibble: 653 × 13
   index   assessment_id scope timing                   internationalTrade score         severity ancestry virus ias   text  description                                       code 
   <chr>   <chr>         <chr> <chr>                    <chr>              <chr>         <chr>    <chr>    <chr> <chr> <chr> <chr>                                             <chr>
 1 threats 3299247       NA    Ongoing                  NA                 Low Impact: 3 NA       NA       NA    NA    NA    Agro-industry farming                             2_1_3
 2 threats 3299247       NA    Past, Unlikely to Return NA                 Past Impact   NA       NA       NA    NA    NA    Scale Unknown/Unrecorded                          2_3_4
 3 threats 3299247       NA    Ongoing                  NA                 Low Impact: 3 NA       NA       NA    NA    NA    Nomadic grazing                                   2_3_1
 4 threats 3299247       NA    Ongoing                  NA                 Low Impact: 3 NA       NA       NA    NA    NA    Intentional use (species is the target)           5_1_1
 5 threats 3299247       NA    Ongoing                  NA                 Low Impact: 3 NA       NA       NA    NA    NA    Agro-industry grazing, ranching or farming        2_3_3
 6 threats 3299247       NA    Ongoing                  NA                 Low Impact: 3 NA       NA       NA    NA    NA    Problematic native species/diseases               8_2  
 7 threats 3299247       NA    Ongoing                  NA                 Low Impact: 3 NA       NA       NA    NA    NA    Persecution/control                               5_1_3
 8 threats 3299247       NA    Ongoing                  NA                 Low Impact: 3 NA       NA       NA    NA    NA    Unintentional effects (species is not the target) 5_1_2
 9 threats 3299247       NA    Ongoing                  NA                 Low Impact: 3 NA       NA       NA    NA    NA    Small-holder grazing, ranching or farming         2_3_2
10 threats 3299247       NA    Ongoing                  NA                 Low Impact: 3 NA       NA       NA    NA    NA    Trend Unknown/Unrecorded                          7_1_3
# ℹ 643 more rows
# ℹ Use `print(n = ...)` to see more rows

So, how do you know what elements are available for you to extract data from? The short answer is you can call element_names() to get them:

element_names()

 [1] "assessment_date"               "assessment_id"                 "assessment_points"             "assessment_ranges"             "biogeographical_realms"        "citation"                     
 [7] "conservation_actions"          "conservation_actions_in_place" "credits"                       "criteria"                      "errata"                        "faos"                         
[13] "growth_forms"                  "habitats"                      "latest"                        "lmes"                          "locations"                     "population_trend"             
[19] "possibly_extinct"              "possibly_extinct_in_the_wild"  "red_list_category"             "references"                    "researches"                    "scopes"                       
[25] "sis_taxon_id"                  "stresses"                      "supplementary_info"            "systems"                       "taxon"                         "taxon_common_names"           
[31] "taxon_ssc_groups"              "taxon_synonyms"                "threats"                       "url"                           "use_and_trade"                 "year_published"      

The long answer is that the element names are simply the named elements in a parsed assessment data object. So you could just as well run names(felidae_full[[1]]) to get the same list of element names.

Pass any of the above element names into extract_element() to get a tidy dataframe of those elements.

Part 2 - Gather habitats & threats for a custom list of species

In Part 1, we showed how to stay completely within the API to get habitats and threats for the felidae. What if you have your own list of binomial names?

For the sake of this tutorial, let’s build a quick tibble() with some species in it:


my_species <- dplyr::tibble(genus = c("Panthera", "Diceros", "Cyclura"), 
                            species = c("leo", "bicornis", "pinguis"))

We could get ‘minimal’ assessment data for the first species in our list, just to see what it looks like:

assessments_by_name(api, 
                    genus = my_species$genus[1], 
                    species = my_species$species[1])

A single species on its own probably isn’t that useful, so let’s write a quick loop to iterate over each Latin binomial and get all the latest global assessments:

assessments <-list()

for(i in 1:nrow(my_species)){
  assessments[[i]] <- assessments_by_name(api, 
                                          genus = my_species$genus[i], 
                                          species = my_species$species[i])
}

# Unlist into a tibble
a <- dplyr::bind_rows(assessments)

# Filter on latest global assessments
a <- a %>% 
  dplyr::filter(latest == TRUE & scopes_code == 1)

As before, we can now pass our list of assessment IDs like so:

full_data <- assessment_data_many(api, 
                                  unique(a$assessment_id),
                                  wait_time=0.5)

We can now extract habitats and threats with:

habitats <- extract_element(full_data, "habitats")
threats <- extract_element(full_data, "habitats")