Getting Started

Introduction

This vignette demonstrates a full ezTrack workflow: importing tracking data with non-standard column names, cleaning and standardizing it, converting it to a spatial object, generating summary tables, visualizing fix rates and latitude over time, and plotting tracks and home ranges on an interactive map.

1. Import and format tracking data

We pass a dataset of GPS-tagged migratory shorebirds to ez_track(). If column names aren’t provided, ez_track() will automatically attempt to guess which columns correspond to ID, timestamp, longitude, and latitude.

data(godwit_tracks)
head(godwit_tracks)
#>      individual.local.identifier           timestamp location.long location.lat
#> 3935                     animal1 2024-12-31 16:00:00     -15.84644     16.33822
#> 3936                     animal1 2024-12-31 20:00:00     -15.82790     16.38281
#> 3937                     animal1 2024-12-31 22:00:00     -15.82829     16.38226
#> 3938                     animal1 2025-01-01 00:00:00     -15.82715     16.38327
#> 3939                     animal1 2025-01-01 04:00:00     -15.82761     16.38304
#> 3940                     animal1 2025-01-01 10:00:00     -15.84629     16.32770

tracks <- ez_track(
  data = godwit_tracks
)
#> Detected columns - id: individual.local.identifier, timestamp: timestamp, x: location.long, y: location.lat
#> Removed 852 row(s) with missing or duplicate values.

If automatic column guessing fails or guesses incorrectly, you can manually specify which columns represent the ID, timestamp, longitude, and latitude.

tracks_manual <- ez_track(
  data = godwit_tracks,
  id = 'individual.local.identifier',
  timestamp = 'timestamp',
  x = 'location.long',
  y = 'location.lat',
)
#> Detected columns - id: individual.local.identifier, timestamp: timestamp, x: location.long, y: location.lat
#> Removed 852 row(s) with missing or duplicate values.

You can also subsample the dataset using the subsample() argument, which limits the number of location fixes per time unit. Use a simple string format such as “1 per hour” or “2 per day” to control the sampling frequency.

tracks_subsampled <- ez_track(
  data = godwit_tracks,
  subsample = "2 per hour"
)
#> Detected columns - id: individual.local.identifier, timestamp: timestamp, x: location.long, y: location.lat
#> Removed 852 row(s) with missing or duplicate values.
#> Subsampled to 2 fix(es) per hour

2. Tracking data summary reports

Summary reports can be computed for each individual using ez_summary(). For easy use in reports or presentations, HTML reports can be generated using report = TRUE. Summaries can also be filtered by date using the start_date and end_date arguments.

The following summary statistics are returned for each unique id:

summary_table <- ez_summary(tracks)
summary_table
#>        id n_fixes      first_location       last_location
#> 1 animal1    1095 2024-12-31 16:00:00 2025-04-25 14:00:00
#> 2 animal2    1153 2024-12-31 16:00:00 2025-04-27 22:00:00
#> 3 animal3    1022 2024-12-31 16:00:00 2025-04-23 16:00:00
#> 4 animal4     214 2024-12-31 16:00:00 2025-04-27 16:00:00
#> 5 animal5     223 2024-12-31 16:00:00 2025-04-27 16:00:00
#> 6 animal6     551 2024-12-31 16:00:00 2025-04-27 16:00:00
#>   tracking_duration_days fixes_per_day median_interval_hours max_time_gap_days
#> 1                 114.92          9.53                     2              0.33
#> 2                 117.25          9.83                     2              1.00
#> 3                 113.00          9.04                     2              1.00
#> 4                 117.00          1.83                     6             10.00
#> 5                 117.00          1.91                     6             13.38
#> 6                 117.00          4.71                     4              1.00
#>   distance_km avg_speed_kmh
#> 1     5649.19          2.05
#> 2     5495.39          1.95
#> 3     6370.80          2.35
#> 4     2414.07          0.86
#> 5     2372.16          0.84
#> 6     5438.92          1.94

3. Visualize latitude over time

ez_latitude_plot() can be used to visualize latitudinal movement (north-south) over time for each tracked animal.

ez_latitude_plot(tracks)

The plot supports:

ez_latitude_plot(
  tracks,
  facet = TRUE,
  start_date = "2025-01-01",
  end_date = "2025-04-28",
  date_breaks = "2 months",
  date_format = "%b"
)

4. Visualize fix rate over time

ez_fix_rate_plot() can be used to visualize fix rates over time for each tracked animal, using a tick mark to represent each location fix.

ez_fix_rate_plot(tracks)

The plot supports:

5. Map tracks and home ranges

We can display tracks using an interactive Leaflet map with ez_map() with a simple command.

ez_map(tracks)

As well as with date range filters and a variety of style arguments.

ez_map(tracks,
  start_date = "2025-04-10",
  end_date = "2025-04-28",
  point_color = "timestamp",
  point_size = 2,
  path_opacity = 0.3)

6. Estimate home ranges

Individual or population-level Minimum Convex Polygons (MCP) or Kernel Density Estimate (KDE) home ranges can be created with ez_home_range().

home_ranges_mcp <- ez_home_range(tracks, method = 'mcp', level = 95, start_date = '2025-04-12')
#> Registered S3 methods overwritten by 'adehabitatMA':
#>   method                       from
#>   print.SpatialPixelsDataFrame sp  
#>   print.SpatialPixels          sp

The result is an sf object containing one home range polygon per tracked individual or population (if population = TRUE).

Home ranges can be visualized with ez_map.

ez_map(home_ranges = home_ranges_mcp)

Home ranges can also be mapped alongside tracking data. In this example, we use the start_date argument to ensure the tracking data aligns temporally with the home range period.

ez_map(tracks, home_ranges = home_ranges_mcp, start_date = '2025-04-12')

Developer notes

To update vignette pkgdown site: pkgdown::build_site()