knitr::opts_chunk$set(echo = TRUE)
In this vignette we show a typical workflow using the etn package to retrieve acoustic telemetry data from ETN. We will also use the packages dplyr for data exploration, lubridate to handle datetime data and leaflet for interactive visualizations.
To start, load the etn package:
library(etn)
And the other packages (with installation if necessary):
other_pkgs <- c("dplyr", "lubridate", "leaflet") # install missing packages pkgs_to_install <- other_pkgs[!other_pkgs %in% rownames(installed.packages())] install.packages(pkgs_to_install) # load packages library(dplyr) library(lubridate) library(leaflet)
Connect with your user credentials (as received by VLIZ) to the database. To not expose such confidential information, you could opt to use environment variables:
con <- connect_to_etn(Sys.getenv("userid"), Sys.getenv("pwd")) # This is the default, so you could also use connect_to_etn()
Using con
as variable to store the collection is not mandatory, but it makes your life much easier as con
is the default value of the argument connection
, present in every other function of this package.
A researcher typically works in the context of one or more animal projects. As the project codes are not always easy to remember, let's start by getting an overview of all projects:
all_projects <- get_animal_projects()
Show a preview:
all_projects %>% head(10)
If you know the project code
already and you are just interested to get more information about it, you can specify it in the get_animal_projects()
function directly:
projects_code <- c("2014_demer", "2015_dijle") projects_study <- get_animal_projects(animal_project_code = projects_code) projects_study
This is exactly the same as retrieving all projects first and filtering them afterwards based on column project_code
:
all_projects %>% filter(project_code %in% c(projects_code))
To list all available animal project codes as a vector, you can use list_animal_project_codes()
, one of the etn functions in the list_*
family:
list_animal_project_codes() %>% head(10)
By using get_animals()
you can retrieve information about each animal (animal_id
), such as scientific name, length, capture/release date and location, and the attached tag(s) (tag_serial_number
):
animals <- get_animals(animal_project_code = projects_code) animals %>% head(10)
What species and how many individuals are tracked for the projects 2014_demer
and 2015_dijle
?
animals %>% count(scientific_name)
Let's say we are interested in the tracking data of Wels catfish (Silurus glanis) in 2014. You can retrieve the detection history using get_acoustic_detections()
:
detections_silurus <- get_acoustic_detections( animal_project_code = projects_code, start_date = "2014-01-01", end_date = "2015-01-01", # The end date is exclusive scientific_name = "Silurus glanis" )
Preview:
detections_silurus %>% head(10)
Which individuals have been detected (animal_id
) and in which period?
detections_silurus_period <- detections_silurus %>% mutate(date = date(date_time)) %>% group_by(animal_id) %>% summarize( start = min(date), end = max(date) ) detections_silurus_period
Notice we group by animal_id
, the unique identifier of the fish. However, if the fish has only been tagged once (as typically occurs), we could use acoustic_tag_id
as well, i.e. the identifier picked up by acoustic receivers:
detections_silurus %>% mutate(date = date(date_time)) %>% group_by(acoustic_tag_id) %>% summarize( start = min(date), end = max(date) )
We can also get the tracking duration of each fish:
detections_silurus_duration <- detections_silurus %>% group_by(animal_id) %>% summarize(duration = max(date_time) - min(date_time)) detections_silurus_duration
How many times has an individual has been detected?
detections_silurus %>% group_by(animal_id) %>% count()
At how many detection stations have the individuals been detected?
detections_silurus %>% group_by(animal_id) %>% distinct(station_name) %>% count()
Which stations have been involved? You can retrieve them using list_values
function applied to column station_name
:
stations_silurus <- detections_silurus %>% list_values(station_name) stations_silurus
Notice how a detection station can be linked to multiple deployments:
detections_silurus %>% distinct(station_name, deployment_id) %>% group_by(station_name) %>% add_tally() %>% arrange(desc(n))
Sometimes it's interesting to know the number of detections per station:
n_detect_station <- detections_silurus %>% group_by(station_name) %>% count() n_detect_station
It's also interesting to know the number of unique individuals per station:
n_silurus_station <- detections_silurus %>% distinct(station_name, animal_id) %>% group_by(station_name) %>% count() n_silurus_station
To get more information about the tags involved in detections_silurus
, you can use the function get_tags
, which returns tag related information such as serial number, manufacturer, model, and frequency:
tags_id <- list_values(detections_silurus, acoustic_tag_id) tags_silurus <- get_tags(acoustic_tag_id = tags_id) tags_silurus
You can also retrieve such information by tag_serial_number
:
tags_serial <- unique(detections_silurus$tag_serial_number) tags_silurus <- get_tags(tag_serial_number = tags_serial) tags_silurus
However, keep in mind that there is a fundamental difference between the arguments acoustic_tag_id
and tag_serial_number
: the tag_serial_number
identifies the device, which could contain multiple tags or sensors and thus multiple acoustic_tag_id
.
All possible acoustic_tag_id
can be retrieved with the correspondent list_*
function:
list_acoustic_tag_ids() %>% head(10)
The detection of Wels catfishes has been possible thanks to one or more acoustic network projects, mentioned in field acoustic_project_code
. You can retrieve them via the list function list_values()
:
acoustic_project_codes <- detections_silurus %>% list_values(acoustic_project_code) acoustic_project_codes
To get more information about these acoustic networks, you can use function get_acoustic_projects()
acoustic_projects_silurus <- get_acoustic_projects( acoustic_project_code = acoustic_project_codes ) acoustic_projects_silurus
You can retrieve the full list of acoustic network projects with the correspondent list_*
function:
list_acoustic_project_codes() %>% head(10)
You can retrieve deployment information related to the acoustic networks in acoustic_project_codes
by using get_acoustic_deployments()
function:
deployments <- get_acoustic_deployments( acoustic_project_code = acoustic_project_codes ) deployments
These are the deployments of the acoustic receivers involved in detections_silurus
:
deploys_silurus <- detections_silurus %>% list_values(deployment_id) deploys_silurus
More information about them can be retrieved via get_acoustic_deployments()
function with argument deployment_id
:
deployments_silurus <- get_acoustic_deployments( deployment_id = deploys_silurus ) deployments_silurus
Deployment duration:
deployments_silurus_duration <- deployments_silurus %>% mutate(duration = as.duration(recover_date_time - deploy_date_time)) %>% select(deployment_id, station_name, duration) %>% arrange(deployment_id) deployments_silurus_duration
Number of days a deployment detected the passage of one or more individuals:
n_active_days_deployments_silurus <- detections_silurus %>% mutate(date = date(date_time)) %>% distinct(deployment_id, station_name, date) %>% group_by(deployment_id, station_name) %>% summarize(n_days = n(), .groups = "drop") %>% ungroup() n_active_days_deployments_silurus
Relative detection duration, i.e. number of days with at least one detection divided by deployment duration:
rel_det_duration_silurus <- n_active_days_deployments_silurus %>% left_join( deployments_silurus_duration, by = c("deployment_id", "station_name") ) %>% mutate( relative_detection_duration = n_days * (24 * 60 * 60) / as.numeric(duration) ) %>% select(deployment_id, station_name, relative_detection_duration) rel_det_duration_silurus
Aside standard graphs, the geographical component of telemetry data makes interactive maps particularly useful. The package leaflet
is quite popular to create such kind of visualizations.
We can for example create a map of the involved stations showing the station name and the acoustic project code it belongs to as pop-ups. First, we retrieve the coordinates of the stations:
geo_info_stations <- detections_silurus %>% distinct( station_name, deploy_latitude, deploy_longitude, acoustic_project_code ) %>% arrange(station_name) geo_info_stations
To be able to produce the desired map:
leaflet(geo_info_stations) %>% addTiles() %>% addMarkers( lng = ~deploy_longitude, lat = ~deploy_latitude, popup = ~paste0("Station: ", station_name, " (", acoustic_project_code, ")") )
We can visualize the number of detections per station, n_detect_station
, by joining it with geo_info_stations
:
# Create a continuous colour palette function pal <- colorNumeric( palette = "viridis", domain = n_detect_station$n ) n_detect_station %>% left_join( geo_info_stations, by = "station_name" ) %>% leaflet() %>% addTiles() %>% addCircleMarkers( lng = ~deploy_longitude, lat = ~deploy_latitude, radius = ~log(n), color = ~pal(n), fillOpacity = 0.8, stroke = FALSE, popup = ~paste( sep = "<br/>", paste0("Station: ", station_name, " (", acoustic_project_code, ")"), paste0("# detections: ", n) ) ) %>% addLegend( title = "Detections", pal = pal, values = ~n )
In a similar way we can visualize the number of detected individuals per station, n_silurus_station
:
# Create a continuous colour palette function pal <- colorNumeric( palette = "viridis", domain = n_silurus_station$n ) n_silurus_station %>% left_join( geo_info_stations, by = "station_name" ) %>% leaflet() %>% addTiles() %>% addCircleMarkers( lng = ~deploy_longitude, lat = ~deploy_latitude, radius = ~n, color = ~pal(n), fillOpacity = 0.8, stroke = FALSE, popup = ~paste( sep = "<br/>", paste0("Station: ", station_name, " (", acoustic_project_code, ")"), paste0("# detected individuals: ", n) ) ) %>% addLegend( title = "Detected individuals", pal = pal, values = ~n )
We can also make a map of the relative detection duration of the deployments. First, we have to retrieve the deployment geographical coordinates:
geo_info_deploys <- detections_silurus %>% distinct( deployment_id, deploy_latitude, deploy_longitude, station_name, acoustic_project_code ) %>% arrange(station_name) geo_info_deploys
We are ready to create the desired map, where we show the deployment ID, the station name and the network project as popups:
# Create a continuous colour palette function pal <- colorNumeric( palette = "viridis", domain = rel_det_duration_silurus$relative_detection_duration ) rel_det_duration_silurus %>% left_join( geo_info_deploys, by = c("deployment_id", "station_name") ) %>% leaflet() %>% addTiles() %>% addCircleMarkers( lng = ~deploy_longitude, lat = ~deploy_latitude, radius = ~100 * relative_detection_duration, color = ~pal(relative_detection_duration), fillOpacity = 0.8, stroke = FALSE, clusterOptions = markerClusterOptions(), popup = ~paste( sep = "<br/>", paste0("DeploymentID: ", deployment_id), paste0("Station: ", station_name, " (", acoustic_project_code, ")"), paste0("# relative detection duration: ", round(relative_detection_duration, 2)) ) ) %>% addLegend( title = "Relative detection duration", pal = pal, values = ~relative_detection_duration )
Do you want to add the temporal component to visualize the fish movement? Take a look at the moveVis package.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.