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