1 Load libaries

library(ggplot2)
library(move)
library(move2)
library(trackdf)
library(trajr)
library(circular)
library(wildlifeDI)
library(move2)
library(adehabitatLT)
library(igraph)

 

2 Managing collected data

Three data types are monitored in the field:
- 1. data from sensors: a list of sensors, here, GPS collars
- 2. data from animals: a list of individual animals equipped with GPS collars (tags)
- 3. data of events: a list of logs (per unit of time) with GPS positions for each tagged animal (deployment)

 

knitr::include_graphics('./movement.png')
figure from movebank

 

2.1 Get (load) RData file

A full dataset of logs of individual dogs for all sessions, acquired by the ANR project SEAdogSEA.

 

load("mydata.rda")

 

2.1.1 Display the structure of the dataframe using ‘str’

str(all_sessions)
## tibble [224,665 × 9] (S3: tbl_df/tbl/data.frame)
##  $ session     : num [1:224665] 1 1 1 1 1 1 1 1 1 1 ...
##  $ dog_id      : chr [1:224665] "D206" "D206" "D206" "D206" ...
##  $ dogName_en  : chr [1:224665] "Mhee" "Mhee" "Mhee" "Mhee" ...
##  $ village_name: chr [1:224665] "Huak (4)" "Huak (4)" "Huak (4)" "Huak (4)" ...
##  $ logtime     : POSIXct[1:224665], format: "2019-11-14 00:16:23" "2019-11-14 01:03:36" ...
##  $ habitat     : chr [1:224665] "teak" "urban" "urban" "urban" ...
##  $ distance    : num [1:224665] 51.1 19.3 39.9 19.6 19.1 ...
##  $ long        : num [1:224665] 101 101 101 101 101 ...
##  $ lat         : num [1:224665] 19.1 19.1 19.1 19.1 19.1 ...

 

 

2.1.2 Distribution of distances between each log and the house of dog owner (all sessions) for all dogs.

ggplot(data = all_sessions,aes(x=distance, colour = dog_id))+
  geom_density() +
  labs(title="Distribution of distances between logs and dog's owner house")  +
  theme_classic() + theme(legend.position="none")

 

 

3 Visualization of movement

A first visualization using the package “move”
Here, we select all sessions for the dog “D211”

mydog <- all_sessions |>
  dplyr::select(long,lat,logtime,dog_id) |>
  dplyr::arrange(logtime)|>
  dplyr::filter(dog_id == "D211")

 

Prepare a move object

mydog_session <- move(
  x=mydog$long, y=mydog$lat,
  time=as.POSIXct(mydog$logtime, format="%Y-%m-%d %H:%M:%OS", tz="Asia/Bangkok"),
  proj=CRS("+proj=longlat +ellps=WGS84 +datum=WGS84"),
  data=mydog,
  animal=mydog$dog_id)

 

Print the movement of “D211”

 

plot(mydog_session, xlab="Longitude", ylab="Latitude",main="Movement of D211", 
     type="l", pch=16, lwd=0.5)
points(mydog_session, pch=20, cex=0.5)

 

Prepare a move2 object

 

mydog_session2 <- move2::mt_as_move2(mydog_session,
                                     coords = c("long", "lat"), time_column = "logtime",
                                     track_id_column = "dog_ID") |> 
  sf::st_set_crs(4326L)

 

Plot using mapview

 

mapview::mapview(mydog_session2)

 

Prepare a track object of D211 and plot using ggplot

 

track_mydog <- track(x = mydog$long, y = mydog$lat, t = mydog$logtime,
                     id = mydog$dog_id, proj = "+proj=longlat", tz = "Asia/Bangkok")

ggplot(data = track_mydog) +
  aes(x = x, y = y, color = id) +
  geom_path() +
  coord_map()

 

Create a trajectory from the log coordinates of D211 using ‘trajr’ and plot

 

trj <- TrajFromCoords(mydog|>
                        dplyr::select(long,lat),
                      spatialUnits = "pixels")
plot(trj, xlab="Longitude", ylab="Latitude")

 

Using ‘circular’ to identify potential corridor

 

mydog_sessionCorr <- corridor(mydog_session)
plot(mydog_sessionCorr, type="l", xlab="Longitude", ylab="Latitude", col=c("black", "grey"), lwd=c(1,2))
legend("bottomleft", c("Corridor", "Non-corridor"), col=c("black", "grey"), lty=c(1,1), bty="n")

 

If center=TRUE: the center of the coordinate system is the center of the track. Units are in meters

 

mydog_session.prj <- spTransform(mydog_session, center=TRUE) 
dBB.mydog_session <- brownian.bridge.dyn(mydog_session.prj, ext=.85, raster=100, location.error=20)
UDmydog_session <- getVolumeUD(dBB.mydog_session)

 

Plot the Utization Distribution (UD) of D211 The UD represents the minimum area in which an animal has some specified probability of being located

 

plot(UDmydog_session, main="UD and contour lines for D211")
contour(UDmydog_session, levels=c(0.5, 0.95), add=TRUE, lwd=c(0.5, 0.5), lty=c(2,1))

 

plot UD85 and UD50

 

par(mfrow=c(1,2))
## mantaining the lower probabilities
ud95 <- UDmydog_session
ud95[ud95>.95] <- NA
plot(ud95, main="UD95")
## UD 50
ud50 <- UDmydog_session<=.5
plot(ud50, main="UD50")

 

3.0.1 Analysing speed

 

Compute speed and accelation using ‘TrajDerivatives’, plot isong

 

# Smooth before calculating derivatives
smoothed <- TrajSmoothSG(trj, 2, 15)
# Calculate speed and acceleration
derivs <- TrajDerivatives(smoothed)
# Plot change-in-speed and speed
plot(derivs$acceleration ~ derivs$accelerationTimes, type = 'l', col = 'red', 
     yaxt = 'n',
     xlab = 'Time (s)',
     ylab = expression(paste('Change in speed (', m/s^2, ')')))
axis(side = 2, col = "red")
lines(derivs$speed ~ derivs$speedTimes, col = 'blue')
axis(side = 4, col = "blue")
mtext('Speed (m/s)', side = 4, line = 3)
abline(h = 0, col = 'lightGrey')

 

Plot speed over time.

 

# Calculate hovering intervals
intervals <- TrajSpeedIntervals(trj, slowerThan = 4)
plot(intervals)

 

4 Contacts

 

The package ‘wildlifeDI’ allows the investigation of contacts between individuals. - 1. create as sf object of the full data (all_sessions) - 2. transform into a move2 object

 

# sf object
alldog_sf  <- sf::st_as_sf(all_sessions, coords = c("long", "lat"),
                           crs= "+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0") |>
  dplyr::select(logtime,dog_id,session,village_name,habitat)
# move2 object
alldog_obj <- mt_as_move2(alldog_sf ,
                          time_column = "logtime", track_id_column = "dog_id", session = "session")

 

Plot contact distances, selecting one session (“3) and villages 6 and 7 (one reason is to decrease the computation time)

dcPlot(alldog_obj |> 
         dplyr::filter(session =="3",
                       village_name %in% c("Huay Muang (6)", "Sun Ti Suk (7)")),
       tc=15*60,dmax=1000)

## [1] 156.5153 439.2527 570.5236 833.0654

 

Compute contact distances, selecting one session (“3) and villages 6 and 7 (one reason is to decrease the computation time)

doecons <- conProcess(alldog_obj |> 
                        dplyr::filter(session =="3",
                        village_name %in% c("Huay Muang (6)", "Sun Ti Suk (7)")),
                       dc=50,tc=15*60)

doephas <- conPhase(doecons, pc=60*60)

consum <- doephas |>
  sf::st_drop_geometry() |>
  dplyr::filter(!is.na(contact_pha)) |>
  dplyr::group_by(contact_pha) |>
  dplyr::summarise(
    nfix = dplyr::n(),
    t1 = min(logtime),
    t2 = max(logtime),
    duration = max(logtime)-min(logtime),
    avg_d = mean(contact_d,na.rm=T),
    min_d = min(contact_d,na.rm=T),
    max_d = max(contact_d,na.rm=T)
  )

consum

 

Map contacts of dog “D219” (contact 1) with other dogs (other contacts)

pha_lin <- doephas |>
  dplyr::filter(!is.na(contact_pha)) |>
  dplyr::group_by(contact_pha) |>
  dplyr::summarise(n = dplyr::n(),do_union=FALSE) |>
  dplyr::filter(n > 1) |>
  sf::st_cast("LINESTRING")

ggplot() + 
  geom_sf(data=alldog_obj |> 
            dplyr::filter(session =="3",
                        village_name %in% c("Huay Muang (6)", "Sun Ti Suk (7)")),
          aes(color=mt_track_id(alldog_obj |> 
                                  dplyr::filter(session =="3",
                                                village_name %in% c("Huay Muang (6)", "Sun Ti Suk (7)"))))) +
  geom_sf(data=pha_lin)

 

Prepare object for network analysis

cons <- conProcess(alldog_obj |> 
                     dplyr::filter(session =="3",
                                   village_name %in% c("Huay Muang (6)", "Sun Ti Suk (7)")),
                   dc=50,tc=15*60,
                   return='contacts')
cons

 

Prepare igraph object

tab_cnt <- cons |>
  dplyr::count(id1,id2)

gr <- graph_from_data_frame(tab_cnt,directed=FALSE)
E(gr)$weight <- tab_cnt$n
plot(gr)

 

Detect modules and plot unipartite network of contacts between individual dogs

# Community detection
fastgreedy.community(gr)
## IGRAPH clustering fast greedy, groups: 3, mod: 0.46
## + groups:
##   $`1`
##   [1] "D219" "D220" "D236" "D237" "D238"
##   
##   $`2`
##   [1] "D245" "D246" "D247" "D248" "D249"
##   
##   $`3`
##   [1] "D242" "D243" "D244"
## 
fc <- cluster_fast_greedy(gr)
V(gr)$color <- fc$membership+1

plot(gr)

 

Map overlap of home range between dogs, villages 6 and 7, session 3

idcol <- mt_track_id_column(alldog_obj |> 
                              dplyr::filter(session =="3",
                                            village_name %in% c("Huay Muang (6)", "Sun Ti Suk (7)")))
mcphr <- alldog_obj |> 
  dplyr::filter(session =="3",
                village_name %in% c("Huay Muang (6)", "Sun Ti Suk (7)")) |>
  dplyr::group_by_at(idcol) |>
  dplyr::summarise() |>
  sf::st_convex_hull()
mapview::mapview(mcphr)
<

 


5 List of some tutorials