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.
# 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
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()

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.
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
scale_fill_gradient(low="white", high="red") + # define the gradient for the fill
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.
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:
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() +
scale_fill_gradient(low="white", high="gold3") +
ggtitle("Contacts between species") +
theme_void()

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
# 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_edge_link(aes(alpha = weight)) +
geom_node_point(aes(size = degree), col = 'darkred') +
scale_size(range = c(0.3, 10)) +
theme_void()

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() +
geom_edge_link(aes(alpha = weight)) +
geom_node_point(aes(size = degree), col = 'darkgreen') +
theme_void()

Exercise: create the network for the other 2 species