Calculate species richness, beta diversity and spatial and temporal dissimilarity
library(knitr)
library(terra)
library(vegan)
library(tmap)
tmap_mode('view')
library(sf)
sf::sf_use_s2(FALSE)
library(tidyverse)
equalareaCRS <- '+proj=laea +lon_0=-73.125 +lat_0=0 +datum=WGS84 +units=m +no_defs'
latam <- st_read('data/latam.gpkg', layer = 'latam', quiet = T)
countries <- st_read('data/latam.gpkg', layer = 'countries', quiet = T)
latam_land <- st_read('data/latam.gpkg', layer = 'latam_land', quiet = T)
latam_raster <- rast('data/latam_raster.tif', lyrs='latam')
hyagouaroundi_P.pred <- readRDS('data/Ppred_samples/hyagouaroundi_P.pred_sample.rds')
cbrachyurus_P.pred <- readRDS('data/Ppred_samples/cbrachyurus_P.pred_sample.rds')
ebarbara_P.pred <- readRDS('data/Ppred_samples/ebarbara_P.pred_sample.rds')
lwiedii_P.pred <- readRDS('data/Ppred_samples/lwiedii_P.pred_sample.rds')
pbrasiliensis_P.pred <- readRDS('data/Ppred_samples/pbrasiliensis_P.pred_sample.rds')
Species richness
Code
time1 <- data.frame(hyagouaroundi=robustbase::colMedians(hyagouaroundi_P.pred[,1:2180]),
cbrachyurus=robustbase::colMedians(cbrachyurus_P.pred[,1:2180]),
ebarbara=robustbase::colMedians(ebarbara_P.pred[,1:2180]),
lwiedii=robustbase::colMedians(lwiedii_P.pred[,1:2180]),
pbrasiliensis=robustbase::colMedians(pbrasiliensis_P.pred[,1:2180]))
time2 <- data.frame(hyagouaroundi=robustbase::colMedians(hyagouaroundi_P.pred[,(2180+1):4360]),
cbrachyurus=robustbase::colMedians(cbrachyurus_P.pred[,(2180+1):4360]),
ebarbara=robustbase::colMedians(ebarbara_P.pred[,(2180+1):4360]),
lwiedii=robustbase::colMedians(lwiedii_P.pred[,(2180+1):4360]),
pbrasiliensis=robustbase::colMedians(pbrasiliensis_P.pred[,(2180+1):4360]))
# sum of occurrence probabilities per grid cell
richness_time1 <- time1 %>% rowSums()
richness_time2 <- time2 %>% rowSums()
# values are the same for all species (see check below) thus I can use one species as example
cbrachyurus_expert_gridcell <- readRDS('data/species_POPA_data/cbrachyurus_expert_gridcell.rds')
PO_time1 <- readRDS('data/species_POPA_data/data_cbrachyurus_PO_time1.rds') %>%
cbind(expert=cbrachyurus_expert_gridcell$dist_exprt) %>%
filter(!is.na(env.bio_10) &!is.na(env.bio_14) & !is.na(env.elev) & !is.na(env.grass) &
!is.na(acce) & !is.na(count) & !is.na(expert))
PO_time2 <- readRDS('data/species_POPA_data/data_cbrachyurus_PO_time2.rds') %>%
cbind(expert=cbrachyurus_expert_gridcell$dist_exprt) %>%
filter(!is.na(env.bio_10) &!is.na(env.bio_14) & !is.na(env.elev) & !is.na(env.grass) &
!is.na(acce) & !is.na(count) & !is.na(expert))
PO_time1_time2 <- rbind(PO_time1 %>% mutate(time=1), PO_time2 %>% mutate(time=2))
preds.richness <- data.frame(PO_time1_time2[,c('X', 'Y', 'pixel', 'area')],
richness_time1, richness_time2)
# rasterise
rast <- latam_raster
rast[] <- NA
rast1 <- rast2 <- rast3 <- terra::rast(rast)
rast1[preds.richness$pixel] <- preds.richness$richness_time1
rast2[preds.richness$pixel] <- preds.richness$richness_time2
rast1 <- rast1 %>% terra::mask(., terra::vect(latam_land))
rast2 <- rast2 %>% terra::mask(., terra::vect(latam_land))
names(rast1) <- 'time1'
names(rast2) <- 'time2'
Code
time1MAP <-
# tm_graticules(alpha = 0.3) +
tm_shape(rast1) +
tm_raster(palette = 'Oranges', midpoint = NA,
# alpha = 0.7,
style= 'cont', breaks = seq(0, 5, 1),
title='SR time1') +
# tm_shape(countries) +
# tm_borders(col='grey60', alpha = 0.4) +
# tm_layout(legend.outside = T, frame.lwd = 0.3, scale=1.2, legend.outside.size = 0.1) +
tm_view(set.view = 3)
time1MAP
Code
# tmap::tmap_save(tm = time1MAP, filename = 'docs/figs/time1MAP_SR.svg', device = svglite::svglite)
# Map of the of the probability of occurrence in the second period (time2: 2014-2021)
time2MAP <-
# tm_graticules(alpha = 0.3) +
tm_shape(rast2) +
tm_raster(palette = 'Purples', midpoint = NA,
alpha = 0.7,
style= 'cont', breaks = seq(0, 5, 1),
title='SR time2') +
# tm_shape(countries) +
# tm_borders(col='grey60', alpha = 0.4) +
# tm_layout(legend.outside = T, frame.lwd = 0.3, scale=1.2, legend.outside.size = 0.1) +
tm_view(set.view = 3)
time2MAP
Code
# tmap::tmap_save(tm = time2MAP, filename = 'docs/figs/time2MAP_SR.svg', device = svglite::svglite)
diffMAP <-
# tm_graticules(alpha = 0.3) +
tm_shape(rast2 - rast1) +
tm_raster(palette = 'PiYG', midpoint = 0,
#alpha = 0.7,
style = 'cont', breaks = seq(-4, 2, 1),
title='SR change') +
# tm_shape(countries) +
# tm_borders(col='grey60', alpha = 0.4) +
# tm_layout(legend.outside = T, frame.lwd = 0.3, scale=1.2, legend.outside.size = 0.1) +
tm_view(set.view = 3)
diffMAP
Code
# tmap::tmap_save(tm = diffMAP, filename = 'docs/figs/diffMAP_SR.svg', device = svglite::svglite)
SR_change <- as_tibble(rast2 - rast1) %>%
rename(diffSR=time2) %>%
mutate(change=ifelse(diffSR<(-0.112), 'neg',
ifelse(diffSR>0.112, 'pos', 'zero')))
SR_change_hist <- ggplot(SR_change) +
geom_histogram(aes(x=diffSR, fill=change), bins = 20) +
scale_fill_manual(values=c('#d01c8b', '#4dac26', '#f7f7f7')) +
labs(x='Change in SR', y='N of grid cells') +
ggpubr::theme_pubclean()
SR_change_hist
IUCN species richness map
Code
cthous_IUCN <- sf::st_read('big_data/cthous_IUCN.shp', quiet = T) %>% sf::st_transform(crs=equalareaCRS)
hyagouaroundi_IUCN <- sf::st_read('big_data/hyagouaroundi_IUCN.shp', quiet = T) %>% sf::st_transform(crs=equalareaCRS)
cbrachyurus_IUCN <- sf::st_read('big_data/cbrachyurus_IUCN.shp', quiet = T) %>% sf::st_transform(crs=equalareaCRS)
ebarbara_IUCN <- sf::st_read('big_data/ebarbara_IUCN.shp', quiet = T) %>% sf::st_transform(crs=equalareaCRS)
lwiedii_IUCN <- sf::st_read('big_data/lwiedii_IUCN.shp', quiet = T) %>% sf::st_transform(crs=equalareaCRS)
pbrasiliensis_IUCN <- sf::st_read('big_data/pbrasiliensis_IUCN.shp', quiet = T) %>% sf::st_transform(crs=equalareaCRS)
# Latam_grid <- st_make_grid(Latam, cellsize = 100000) %>%
# st_intersection(Latam) %>%
# st_sf(gridID=1:length(.), geometry= .) %>%
# st_make_valid() %>% st_cast()
carnivores <- do.call(rbind, list(hyagouaroundi_IUCN %>% select(binomial),
cbrachyurus_IUCN %>% select(binomial),
ebarbara_IUCN %>% select(binomial),
lwiedii_IUCN %>% select(binomial),
pbrasiliensis_IUCN %>% select(binomial))) %>%
st_cast()
# SR_carnivores <- st_join(Latam_grid, carnivores) %>%
# group_by(gridID) %>%
# summarise(SR=ifelse(n_distinct(binomial, na.rm=T)!=0, n(), 0)) %>%
# st_cast() %>% sf::st_transform(crs=4326)
SR_carnivores <- vect(carnivores) %>%
rasterize(., latam_raster, fun='count', 'binomial')
names(SR_carnivores) <- 'SR'
Code
tmap_mode('view')
tmap_mode('plot')
IUCN_SR <-
#tm_graticules(alpha = 0.3) +
tm_shape(SR_carnivores) +
tm_raster(palette = 'Greys',
alpha = 0.7,
style = 'cont',
breaks = seq(0, 5, 1),
title='SR IUCN range maps') +
# tm_shape(countries) +
# tm_borders(col='grey60', alpha = 0.4) +
# tm_layout(legend.outside = T,
# frame.lwd = 0.3, scale=1.2, legend.outside.size = 0.1) +
tm_view(set.view = 3)
IUCN_SR
Code
# tmap::tmap_save(tm = IUCN_SR, filename = 'docs/figs/IUCN_SR.svg', device = svglite::svglite)
Beta diversity
Code
# ratio gamma / alpha -1
gamma <- ncol(time1)
alpha1 <- mean(richness_time1)
beta1 <- round(gamma/alpha1, 3)
# confidence interval
sd1 <- sd(richness_time1)
beta1.high <- round(gamma/(alpha1+sd1), 3)
beta1.low <- round(gamma/(alpha1-sd1), 3)
tibble(gamma=gamma, alpha1=alpha1,
sd1=sd1, beta1=beta1,
beta1.high=beta1.high,
beta1.low=beta1.low) %>%
kable()
5 |
2.61632 |
1.505596 |
1.911 |
1.213 |
4.502 |
Code
# ratio gamma / alpha -1
gamma <- ncol(time2)
alpha2 <- mean(richness_time2)
beta2 <- round(gamma/alpha2, 3)
# confidence interval
sd2 <- sd(richness_time2)
beta2.high <- round(gamma/(alpha2+sd2), 3)
beta2.low <- round(gamma/(alpha2-sd2), 3)
tibble(gamma=gamma, alpha2=alpha2,
sd2=sd2, beta2=beta2,
beta2.high=beta2.high,
beta2.low=beta2.low) %>%
kable()
5 |
2.395093 |
1.467106 |
2.088 |
1.295 |
5.388 |
Code
beta_w_time1 <- gamma/richness_time1
beta_w_time2 <- gamma/richness_time2
betas_time <- tibble(beta = c(beta_w_time1, beta_w_time2),
time = c(rep('time1', length(beta_w_time1)),
rep('time2', length(beta_w_time2))))
## betas
betas_plot <- ggplot(betas_time, aes(x=time, y=beta, fill=time)) +
geom_boxplot(show.legend = F) +
scale_fill_manual(values = c('#e66101', '#5e3c99')) +
scale_y_continuous(limits = quantile(richness_time1, c(0.1, 0.9))) +
labs(x='', y=expression(beta)) +
ggpubr::theme_pubclean()
betas_plot
Code
## alphas
alphas <- data.frame(site=1:nrow(time1),
alpha=c(richness_time1, richness_time2),
time=c(rep('time1', length(alpha1)),
rep('time2', length(alpha2))))
alphas_plot <- ggplot(alphas, aes(x = time, y=alpha, fill=time)) +
geom_boxplot(show.legend = F) +
scale_fill_manual(values = c('#e66101', '#5e3c99')) +
labs(x='', y=expression(alpha)) +
ggpubr::theme_pubclean()
alphas_plot
Code
# ggsave(alphas_plot, filename='docs/figs/alphas_plot.svg',
# width = 3, height = 5, device = 'svg', dpi=200)
Spatial dissimilarity
Code
b.jac1 <- vegdist(time1, method = 'jaccard')
b.jac2 <- vegdist(time2, method = 'jaccard')
# dist
XY <- preds.richness[1:2180,1:2]
dist_XY <- dist(XY, method = 'euclidian')
dist_XY <- as.matrix(dist_XY)
XY_sf <- st_as_sf(XY, coords=c('X','Y'), crs=equalareaCRS)
gridsToKeep <- XY_sf %>%
pull(geometry) %>%
st_distance() %>%
as.data.frame.table() %>%
filter(Freq < units::set_units(500000, 'm')) %>%
mutate(index_keep = paste0(Var1,'-',Var2)) %>%
select(index_keep)
####
# select grid closer than 200km
dist_XY_200km <- dist_XY %>%
as_tibble() %>%
mutate(row = row_number()) %>%
pivot_longer(-row, names_to = 'column',values_to = 'values', names_prefix = 'V') %>%
mutate(index = paste0(row,'-',column)) %>%
filter(index %in% gridsToKeep$index_keep) %>%
select(dist=values)
# distance decay
b.jac1_200km <- b.jac1 %>% as.matrix() %>%
as_tibble() %>%
mutate(row = row_number()) %>%
pivot_longer(-row, names_to = 'column',values_to = 'values', names_prefix = 'V') %>%
mutate(index = paste0(row,'-',column)) %>%
filter(index %in% gridsToKeep$index_keep) %>%
select(jac_time1=values)
b.jac2_200km <- b.jac2 %>% as.matrix() %>%
as_tibble() %>%
mutate(row = row_number()) %>%
pivot_longer(-row, names_to = 'column',values_to = 'values', names_prefix = 'V') %>%
mutate(index = paste0(row,'-',column)) %>%
filter(index %in% gridsToKeep$index_keep) %>%
select(jac_time2=values)
spatial_beta <- bind_cols(dist_XY_200km, b.jac1_200km, b.jac2_200km)
Code
beta_boxplot <- spatial_beta %>%
rename(time1=jac_time1, time2=jac_time2) %>%
mutate(dist=as.factor(round(dist/1000,0))) %>%
filter(dist!=0) %>%
pivot_longer(-dist, names_to = 'time',values_to = 'dissimilarity') %>%
ggplot() +
geom_boxplot(aes(y = dissimilarity, x=dist, fill=time), alpha=0.8, outlier.shape = NA) +
scale_fill_manual(values = c('#e66101', '#5e3c99')) +
stat_summary(fun = median, geom = 'path', linewidth=1,
mapping = aes(y = dissimilarity, x=dist, group=time, col=time),
show.legend = F) +
scale_color_manual(values = c('#e66101', '#5e3c99')) +
labs(x='Distance (km)', y='Beta diversity (Ružička index)', col='', fill='') +
theme_bw()
beta_boxplot
Code
# ggsave(beta_boxplot, filename='docs/figs/beta_boxplot.svg',
# width = 7, height = 5, device = 'svg', dpi=300)
Temporal dissimilarity
Code
calculateBetaTemporal <- function(comm_time1, comm_time2, index='jaccard'){
beta.temp <- data.frame(row=numeric(), beta.temp=numeric())
for(i in 1:nrow(comm_time1)){
comm.matrix <- bind_rows(comm_time1[i,], comm_time2[i,])
beta.temp_i <- data.frame(row=i, beta.temp=as.numeric(vegdist(comm.matrix, index)))
beta.temp <- rbind(beta.temp, beta.temp_i)
}
return(beta.temp)
}
beta.temp <- calculateBetaTemporal(time1, time2)
preds.richness <- bind_cols(preds.richness[1:2180,], beta.temp=beta.temp[,2]) %>%
select(pixel, beta.temp)
rast <- latam_raster
rast[] <- NA
rast3 <- terra::rast(rast)
rast3[preds.richness$pixel] <- preds.richness$beta.temp
rast3 <- rast3 %>% terra::mask(., terra::vect(latam_land))
names(rast3) <- 'beta.temp'
Code
beta_map <-
# tm_graticules(alpha = 0.3) +
tm_shape(rast3) +
tm_raster(palette = '-RdPu', midpoint = NA,
alpha=0.7,
style= 'cont') +
# tm_shape(countries) +
# tm_borders(col='grey60', alpha = 0.4) +
# tm_layout(legend.outside = T, frame.lwd = 0.3, scale=1.2) +
tm_view(set.view = 3)
beta_map
Code
# tmap::tmap_save(tm = beta_map, filename = 'docs/figs/beta_map.svg', device = svglite::svglite)