In this section we will use a different dataset which consist on GPS locations of 3 different species.
We will define our contact network based on proximity between two animals from the GPS location records.

# 1 Exploratory analysis

# libraries we will use
library(dplyr) # for data manipulation
library(sf) # For spatial data manipulation
library(sp) # for spatial data
library(ggplot2) # for making figures
library(purrr) # for network transformation
library(tidygraph) # for network manipulation
library(ggraph) # for plotting networks
# We get the data from the STNet package
GPSc <- STNet::GPSc

First we will see how many locations were recorded during the observation period by species:

GPSc %>%
count(species_type) # count by species
##   species_type     n
## 1       cattle  9309
## 2         deer 11511
## 3          pig  4428

Now lets create a dataset for the nodes.

Nodes <- GPSc %>%
mutate(CollarID = as.character(CollarID)) %>% # convert to character
distinct(CollarID, species_type) # unique IDs

## 1.1 Temporal visualization

Now lets see how does the GPS records varies during the observation period:

Daily <- GPSc %>%
count(Date, species_type) # Count by species and date

ggplot(data = Daily) + # call ggplot
geom_line(aes(x = Date, y = n, color = species_type), size = 1) +
theme_minimal()

## 1.2 Spatial distribution of the records

First we will transform our data into a spatial points object.

GPScSP <- GPSc %>%
st_as_sf(coords = c("X", "Y"), crs = st_crs(4326)) %>% # convert to spatial data
st_transform(st_crs(32615)) # project the data

Now we use geom_sf() to show the recorded locations on a map.

GPScSP %>%
ggplot() + #
geom_sf(aes(color = species_type), alpha = 0.2, size = 0.4) +
theme_minimal() +
theme(legend.position = 'top')

It looks like the 3 different species have movement ranges where they coincide. To identify where are the species coinciding more often we will use a hexagonal grid.

# 2 Species range maps

The STNet package includes a function called HexGrid, which creates a hexagonal grid on a spatial field. Here we will use the extent of our points to create the grid.

# First we create a field that represents the study area:
Border <- as(raster::extent(GPScSP), "SpatialPolygons") %>%
st_as_sf()
# We define the CRS
st_crs(Border) <- st_crs(GPScSP)
# Load the STNet library:
library(STNet)
# We use the HexGrid function:
BorderHex <- HexGrid(cellsize = 500, Shp = Border)
## Warning in proj4string(obj): CRS object has comment, which is lost in output; in tests, see
## https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
## Warning: use *apply and slot directly
## Warning: use *apply and slot directly
# Plot the grid:
plot(BorderHex\$geometry)

Next we wull use another function from the STNet package that counts the number of points per hexagonal cell. The arguments we need are:

• Hex, the hexagonal grid we created.
• Points The locations that we want to count. for this function is also necesary to have installed the package sp, so make sure its installed and loaded.

Now lets plot the movement ranges for the species on the observed period:

# For cattle:
GPScSP %>%
filter(species_type == "cattle") %>% # we filter to only cattle records
HexMap(Hex = BorderHex, .) %>% # count the points per grid cell
ggplot(., aes(fill = N)) + # call ggplot
geom_sf() + # add the spatial layer
ggtitle("Cattle Range") + # add a title
theme_void() #add a theme 

Exercise: Create the range maps for the other 2 species (deer y pig) and use different colors.

# 3 Defining the network:

## 3.1 Defining the contacts:

Now we will define our network. We are interested in all the contacts that happened between animals at a distance of < 1 m.

This function might take some time, if you want to skip this part, the data is available inside the STNet package.

# Lets change the names to test the function:
colnames(GPSc)[c(1, 4, 6, 7)] <- c("id", "date", "Longitude", "Latitude")
# Run the function
Edges <- CreateNetwork(DF = GPSc[,], # This is our data
DTh = 1, # TTthe distance threshold
DateTime = "date", # Name of the variable that indicates the date and time
ID = "id", # name of variable for id
coords = c("Longitude", "Latitude") # Name of variable for coordinated
) # 14,869

To load the data directly from the STNet package we can use the function:

Edges <- STNet::. %>%  # load the dataset from the package
mutate_at(.vars = c('Var1', 'Var2'), .funs = as.character) # convert the variables to character

This dataset includes:

• Distance: distance between the recorded contact.
• DateTime: The time when the contact happened.
• Var1 and Var2: nodes involved in the contact. Remember that since these contacts are registerd from the location of the animals, we don’t know who started the contact, so it is not directed.
• X.x, Y.x, X.y, Y.y: the spatial location of the nodes at that time.

### 3.1.1 Contacts between species:

We can also detect areas where the contacts between species are happening.
For this we will create a subset of the data that includes only contacts between different species.

# Add variable for species
Edges <- Edges %>%
left_join(Nodes, by = c("Var1" = "CollarID")) %>% # Var1 one of the nodes
rename(Sp1 = species_type) %>%
left_join(Nodes, by = c("Var2" = "CollarID")) %>% # Var 2 is the other node
rename(Sp2 = species_type)

InterSp <- Edges %>%
filter(Sp1 != Sp2) %>% # select contacts where the species are different
data.frame()
# we create a projected dataset
InterSp_sp <- InterSp %>%
dplyr::select(DateTime, Var1, Var2, Sp1, Sp2, X.x, Y.x) %>%
st_as_sf(coords = c("X.x", "Y.x"), crs = st_crs(4326)) %>%
st_transform(st_crs(32615))

# Count the observations per grid cell
IspH <- HexMap(BorderHex, Points = InterSp_sp)

# make the figure
ggplot(IspH, aes(fill = N)) +
geom_sf() +
ggtitle("Contacts between species") +
theme_void()

## 3.2 Define the nodes:

We previously defined the nodes, we can see that there are 36 animals in our network.

Nodes %>%
count(species_type)
##   species_type  n
## 1       cattle 13
## 2         deer 16
## 3          pig  7

## 3.3 Creating the network:

# Create the network:
G1 <- as_tbl_graph(Edges[c("Var1", "Var2")], directed = F) %N>%
mutate(degree = centrality_degree()) %>%
left_join(Nodes, by = c('name' = 'CollarID')) %E>%
mutate(N = as.integer(1)) %>% # Create a variable to count the number of contact:
convert(to_simple) %E>%  # now we will convert it to a simple network
mutate(weight = map_int(.orig_data, ~.x %>% pull(N) %>% sum()))  # We have to sum all the repeated movements

ggraph(graph = G1) +
geom_node_point(aes(size = degree), col = 'darkred') +
scale_size(range = c(0.3, 10)) +
theme_void()

## 3.4 Networks by species:

We can filter the nodes based on the species type to create a figure of only one species type.

G1 %N>%
filter(species_type == 'cattle') %>%
ggraph() +
theme_void()