Exercise A

Task 1: Import your data

Create a new R-file and import the wild boar data.

library("readr")
library("sf")

wildschwein_BE <- read_delim("datasets/wildschwein_BE_2056.csv", ",")

wildschwein_BE <- st_as_sf(wildschwein_BE, coords = c("E", "N"), crs = 2056)

Note:

  • that this dataset is already converted to EPSG 2056
  • the coordinates are stored in the columns (E/N)

Task 2: Getting an overview

Calculate the time difference between subsequent rows as described in the demo. You can calculate the time difference using the function difftime_secs() (see below) in combination with lead() (see lead() / lag()). Store the time difference in a new column (e.g. timelag).

difftime_secs <- function(later, now){
    as.numeric(difftime(later, now, units = "secs"))
}

Now inspect your data in more detail. Try to answer the following questions:

  • How many individuals were tracked?
  • For how long were the individual tracked? Are there gaps?
  • Were all individuals tracked concurrently or sequentially?
  • What is the temporal sampling interval between the locations?
Important

summarise() tries to coerce all (Point-) geometries into one object, which can take along time. To avoid this, use st_drop_geometry() before using summarise().

Task 3: Distance between locations

Similar to how we calculated the timelag between subsequent locations, we can calculate the distance like so:

later <- lag(wildschwein_BE$geometry)
now <- wildschwein_BE$geometry

st_distance(later, now, by_element = TRUE)  # by_element must be set to TRUE

However, similar to difftime(), the output has a unit which complicates things. Therefore, it’s simpler to wrap the output in as.numeric(). Let’s make a function for this process:

distance_by_element <- function(later, now){
  as.numeric(
    st_distance(later, now, by_element = TRUE)
  )
}

Use this function to create a new column named steplength with the distance between locations.

Task 4: Deriving distance & speed

In this task we will derive some additional movement parameters from our trajectories. So far our trajectories only consist of a list of time-stamped spatial locations. First let’s calculate the Euclidean distance between subsequent locations using the function st_distance() with the option by_element = TRUE. Store these values in a new column with the name steplength. Next, you can calculate the animals’ speed based on steplength and the timelag (from the last task).

Task 5: Plausibility Check

It’s important to repeatedly visualize our results, to make sure these are plausible. This is much simpler if we just look at a small sample of our dataset. We can use slice() to extract just a couple of rows

wildschwein_sample <- wildschwein_BE |>
  filter(TierName == "Sabi") |> 
  head(100)

We can now visualise the sample using tmap with the *view” mode:

library(tmap)
tmap_mode("view")

tm_shape(wildschwein_sample) + 
  tm_dots()
Figure 7.1: By clicking on the dots, we can see what parameters are associated with each sample.

The wild boar move continuously through space, but our samples are discrete points. It would be helpful to at least see the sequence of these samples. We can do this by casting our points to lines. However, we first need to dissolve our single points into a MULTIPOINT object, just like we had to do in the first week when we calculated the minimum convex polygon per animal (see Input: Calculate Convex Hull). The option do_union = FALSE is a confusing way to preserve the order of the points, see Nils’ question on GitHub.

In addition, we can set OpenStreetMap to be the default basemap, since it’s available at lower zoom levels.

wildschwein_sample_line <- wildschwein_sample |> 
  # dissolve to a MULTIPOINT:
  summarise(do_union = FALSE) |> 
  st_cast("LINESTRING")

tmap_options(basemaps = "OpenStreetMap")

tm_shape(wildschwein_sample_line) +
  tm_lines() +
  tm_shape(wildschwein_sample) + 
  tm_dots()
Figure 7.2: The interconnecting lines help us understand the animal’s movement trajectory.