
# ---------------------------------------------
# 1. Clean environment
# ---------------------------------------------
rm(list = ls())

# ---------------------------------------------
# 2. Load required libraries
# ---------------------------------------------
library(readxl)
library(vegan)      # For Jaccard index
library(dplyr)
library(tidyr)
library(ggplot2)
library(reshape2)
library(ade4)       # For Pianka index
library(pheatmap)
library(RColorBrewer)

# ---------------------------------------------
# 3. Import dataset
# ---------------------------------------------
data <- read_excel("Supplementary_file_3.xlsx")

# Preview first rows
head(data)

# ---------------------------------------------
# 4. Select abundance columns (species)
# ---------------------------------------------
species_data <- data[, c("Anopheles coluzzii", "Anopheles gambiae s.s.", "Anopheles arabiensis", "Anopheles ND", "Aedes", "Culex", 
                         "Corixidae", "Baetidae", "Hybride (coluzzii *gambiae s.s.)")]

colnames(species_data)[colnames(species_data) == "Hybride (coluzzii *gambiae s.s.)"] <- "Hybrid (coluzzii *gambiae s.s.)"

# Select for Anopheles at genera level 

species_data <- data[, c("Anopheles", "Aedes", "Culex","Corixidae", "Baetidae")]

# ---------------------------------------------
# 5. Alternatively extract all species columns from column 4 onward
# ---------------------------------------------
species_data <- data[, 4:ncol(data)]

# Replace NA by 0
species_data[is.na(species_data)] <- 0

# ---------------------------------------------
# 6. Transpose the matrix: species as rows, sites as columns
# ---------------------------------------------
species_matrix <- t(species_data)
rownames(species_matrix) <- colnames(species_data)

# Remove species with total abundance = 0
species_matrix <- species_matrix[rowSums(species_matrix) > 0, ]

# ---------------------------------------------
# 7. Compute Pianka niche overlap index
# ---------------------------------------------
pianka_overlap <- function(mat) {
  mat <- as.matrix(mat)
  mat <- mat / rowSums(mat)  # Normalize abundance profiles
  n <- nrow(mat)
  
  overlap <- matrix(NA, n, n)
  rownames(overlap) <- rownames(mat)
  colnames(overlap) <- rownames(mat)
  
  for (i in 1:n) {
    for (j in 1:n) {
      num <- sum(mat[i, ] * mat[j, ])
      denom <- sqrt(sum(mat[i, ]^2) * sum(mat[j, ]^2))
      overlap[i, j] <- ifelse(denom == 0, NA, num / denom)
    }
  }
  return(overlap)
}

pianka_matrix <- pianka_overlap(species_matrix)
print(round(pianka_matrix, 3))

# ---------------------------------------------
# 8. Presence/absence matrix for Jaccard index
# ---------------------------------------------
presence_absence <- ifelse(species_data > 0, 1, 0)
presence_absence[is.na(presence_absence)] <- 0

# Compute Jaccard distance
jaccard_dist <- vegdist(t(presence_absence), method = "jaccard", binary = TRUE)

# Convert to similarity matrix
jaccard_matrix <- 1 - as.matrix(jaccard_dist)
print(round(jaccard_matrix, 3))

# Convert similarity matrix into a distance object
pianka_dist <- as.dist(1 - pianka_matrix)
jaccard_dist <- as.dist(1 - jaccard_matrix)

# ---------------------------------------------
# 9. Plot Pianka Index Heatmap
# ---------------------------------------------
palette_pianka <- colorRampPalette(brewer.pal(9, "YlGnBu"))(100)

pheatmap(
  pianka_matrix,
  color = palette_pianka,
  cluster_rows = TRUE,
  cluster_cols = TRUE,
  display_numbers = TRUE,
  number_format = "%.2f",
  fontsize = 10,
  fontsize_number = 8,
  border_color = "grey60",
  main = "Pianka Index - Niche Overlap",
  cellwidth = 30,
  cellheight = 30,
  angle_col = 45,
  treeheight_row = 50,
  treeheight_col = 50
)

# ---------------------------------------------
# 10. Plot Jaccard Similarity Heatmap
# ---------------------------------------------
palette_jaccard <- colorRampPalette(brewer.pal(9, "OrRd"))(100)

pheatmap(
  as.matrix(jaccard_matrix),
  color = palette_jaccard,
  cluster_rows = TRUE,
  cluster_cols = TRUE,
  display_numbers = TRUE,
  number_format = "%.2f",
  fontsize = 10,
  fontsize_number = 8,
  border_color = "grey60",
  main = "Jaccard Similarity Index",
  cellwidth = 30,
  cellheight = 30,
  angle_col = 45,
  treeheight_row = 50,
  treeheight_col = 50
)

# =====================================================================
# COMBINED HEATMAP SORTED BY AVERAGE SIMILARITY
# Upper triangle: Pianka index (soft green)
# Lower triangle: Jaccard index (sand/orange)
# =====================================================================

library(tidyverse)
library(vegan)
library(pheatmap)

# --- 1. Data preparation ---------------------------------------------
species_data[is.na(species_data)] <- 0

species_matrix <- t(species_data)
rownames(species_matrix) <- colnames(species_data)

# Remove species with total abundance = 0
species_matrix <- species_matrix[rowSums(species_matrix) > 0, ]

# --- 2. Computation of similarity indices ----------------------------

# Function to compute Pianka niche overlap index
pianka_overlap <- function(mat) {
  mat <- mat / rowSums(mat)  # Normalize abundance profiles
  n <- nrow(mat)
  overlap <- matrix(NA, n, n, dimnames = list(rownames(mat), rownames(mat)))
  
  for (i in 1:n) {
    for (j in 1:n) {
      num <- sum(mat[i, ] * mat[j, ])
      denom <- sqrt(sum(mat[i, ]^2) * sum(mat[j, ]^2))
      overlap[i, j] <- ifelse(denom == 0, NA, num / denom)
    }
  }
  return(overlap)
}

# Pianka matrix
pianka_matrix <- pianka_overlap(species_matrix)

# Presence/absence matrix for Jaccard similarity
presence_absence <- ifelse(species_data > 0, 1, 0)
presence_absence[is.na(presence_absence)] <- 0

# Jaccard similarity matrix (1 - Jaccard distance)
jaccard_matrix <- 1 - as.matrix(
  vegdist(t(presence_absence), method = "jaccard", binary = TRUE)
)

# --- 3. Sorting species by average similarity -------------------------

# Compute the mean of Pianka and Jaccard matrices
mean_similarity <- (pianka_matrix + jaccard_matrix) / 2

# Mean similarity score per species (row average)
mean_score <- rowMeans(mean_similarity, na.rm = TRUE)

# Sort species by decreasing similarity score
species_order <- names(sort(mean_score, decreasing = TRUE))

# Apply sorted order to both matrices
pianka_matrix  <- pianka_matrix[species_order, species_order]
jaccard_matrix <- jaccard_matrix[species_order, species_order]

# --- 4. Create a combined matrix -------------------------------------

combined_matrix <- matrix(
  NA,
  nrow(pianka_matrix), ncol(pianka_matrix),
  dimnames = dimnames(pianka_matrix)
)

# Upper triangle = Pianka
combined_matrix[upper.tri(combined_matrix)] <- pianka_matrix[upper.tri(pianka_matrix)]

# Lower triangle = Jaccard
combined_matrix[lower.tri(combined_matrix)] <- jaccard_matrix[lower.tri(jaccard_matrix)]

# Diagonal = 1
diag(combined_matrix) <- 1



# =====================================================================
# Interpretation:
# - Species located in the upper-left region have high overall similarity.
# - Species located in the lower-right region are more isolated
#   (lower mean similarity scores).
# - Sorting is based on the average of Pianka + Jaccard indices,
#   representing a compromise between niche overlap and co-occurrence.
# =====================================================================

# Soft color palette (yellow-green-blue gradient)
palette_soft <- colorRampPalette(c(
  "#ffffcc",  # very pale yellow
  "#c7e9b4",  # soft green
  "#7fcdbb",  # light turquoise
  "#41b6c4",  # soft blue
  "#225ea8"   # deep blue
))(100)

# Export heatmap as a high-resolution PNG
png("Combined_Heatmap_Pianka_Jaccard.png",
    width = 2200, height = 1500, res = 300)

pheatmap(
  combined_matrix,
  color = palette_soft,
  breaks = seq(0, 1, length.out = 101),
  cluster_rows = FALSE,
  cluster_cols = FALSE,
  display_numbers = TRUE,
  number_format = "%.2f",
  fontsize = 10,
  fontsize_number = 9,
  border_color = "white",
  cellwidth = 25,
  cellheight = 25,
  angle_col = 45,
  #main = "Combined Heatmap: Pianka & Jaccard Indices",
  legend_breaks = seq(0, 1, by = 0.2),
  legend_labels = seq(0, 1, by = 0.2)
)

dev.off()

# Automatically open the exported file
browseURL("Combined_Heatmap_Pianka_Jaccard.png")



# Soft color palette (yellow-green-blue gradient)
palette_soft <- colorRampPalette(c(
  "#ffffcc",  # very pale yellow
  "#c7e9b4",  # soft green
  "#7fcdbb",  # light turquoise
  "#41b6c4",  # soft blue
  "#225ea8"   # deep blue
))(100)

# Export heatmap as a high-resolution TIFF (300 dpi)
tiff("Combined_Heatmap2_Pianka_Jaccard.tif",
     width = 2200, height = 1500, res = 300, units = "px")

pheatmap(
  combined_matrix,
  color = palette_soft,
  breaks = seq(0, 1, length.out = 101),
  cluster_rows = FALSE,
  cluster_cols = FALSE,
  display_numbers = TRUE,
  number_format = "%.2f",
  fontsize = 10,
  fontsize_number = 9,
  border_color = "white",
  cellwidth = 25,
  cellheight = 25,
  angle_col = 45,
  #main = "Combined Heatmap: Pianka & Jaccard Indices",
  legend_breaks = seq(0, 1, by = 0.2),
  legend_labels = seq(0, 1, by = 0.2)
)

dev.off()

# Automatically open the exported file
browseURL("Combined_Heatmap2_Pianka_Jaccard.tif")




# =====================================================================
# NON-TARGET ORGANISM RISK ASSESSMENT
# Following combined heatmaps analysis
# Target species: Anopheles coluzzii
# =====================================================================

# --- 1. TARGET SPECIES DEFINITION -----------------------------------
target_species <- "Anopheles coluzzii"

# Check if target species exists in data
if(!target_species %in% rownames(species_matrix)) {
  # Try to find similar species names
  target_species <- grep("coluzzii", rownames(species_matrix), value = TRUE, ignore.case = TRUE)[1]
  if(is.na(target_species)) {
    stop("Target species 'Anopheles coluzzii' not found in the data.")
  }
  message("Target species identified: ", target_species)
}

# --- 2. EXPOSURE RISK CALCULATION -----------------------------------
# This function calculates exposure risk for non-target organisms
calculate_exposure_risk <- function(pianka_mat, jaccard_mat, species_mat, target) {
  
  # STEP 1: Identify non-target organisms (exclude target species)
  non_target_species <- rownames(pianka_mat)[rownames(pianka_mat) != target]
  
  # STEP 2: Create base results table
  risk_table <- data.frame(
    Non_target_organism = non_target_species,
    Niche_overlap = pianka_mat[non_target_species, target],        # From Pianka matrix
    Habitat_similarity = jaccard_mat[non_target_species, target],  # From Jaccard matrix
    Co_occurrence_rate = NA_real_,                                 # To be calculated
    stringsAsFactors = FALSE
  )
  
  # STEP 3: Calculate co-occurrence rate for each non-target species
  for(i in 1:nrow(risk_table)) {
    non_target_sp <- risk_table$Non_target_organism[i]
    
    # Find sites where target species is present
    target_sites <- which(species_mat[target, ] > 0)
    total_target_sites <- length(target_sites)
    
    if(total_target_sites > 0) {
      # Count sites where both species co-exist
      cooc_sites <- sum(species_mat[non_target_sp, target_sites] > 0)
      risk_table$Co_occurrence_rate[i] <- cooc_sites / total_target_sites
    } else {
      risk_table$Co_occurrence_rate[i] <- 0
    }
  }
  
  # STEP 4: Calculate composite exposure score
  # Formula: Exposure = (Niche × 0.4) + (Habitat × 0.3) + (Co-occurrence × 0.3)
  risk_table$Exposure_score <- (
    risk_table$Niche_overlap * 0.4 +       # Strong weight for niche overlap
      risk_table$Habitat_similarity * 0.3 +  # Medium weight for habitat
      risk_table$Co_occurrence_rate * 0.3    # Medium weight for co-occurrence
  )
  
  # STEP 5: Classify exposure levels
  risk_table$Exposure_level <- cut(
    risk_table$Exposure_score,
    breaks = c(0, 0.25, 0.5, 0.75, 1),
    labels = c("Low", "Moderate", "High", "Very High"),
    include.lowest = TRUE
  )
  
  # STEP 6: Sort by exposure score (descending)
  risk_table <- risk_table[order(-risk_table$Exposure_score), ]
  
  return(risk_table)
}

# Apply the function to calculate risk
exposure_risk <- calculate_exposure_risk(pianka_matrix, jaccard_matrix, species_matrix, target_species)

# --- 3. PUBLICATION-READY TABLE ------------------------------------
library(dplyr)

names(exposure_risk)

publication_table <- exposure_risk %>%
  dplyr::select(
    `Non-target organism` = Non_target_organism,
    `Niche overlap` = Niche_overlap,
    `Habitat similarity` = Habitat_similarity,
    `Co-occurrence rate` = Co_occurrence_rate,
    `Exposure score` = Exposure_score,
    `Exposure level` = Exposure_level
  ) %>%
  dplyr::mutate(
    dplyr::across(2:5, ~ round(., 3))
  )

library(writexl)
write_xlsx(publication_table, "exposure_risk_summary.xlsx")



# Display results
cat("=========================================================================\n")
cat("NON-TARGET ORGANISM RISK ASSESSMENT\n")
cat("Target species:", target_species, "\n")
cat("=========================================================================\n\n")

cat("TOP 15 MOST EXPOSED ORGANISMS:\n")
print(head(publication_table, 15))

# --- 4. DESCRIPTIVE STATISTICS -------------------------------------
exposure_stats <- list(
  `Number of non-target organisms analyzed` = nrow(exposure_risk),
  `Very high exposure organisms` = sum(exposure_risk$Exposure_level == "Very High"),
  `High exposure organisms` = sum(exposure_risk$Exposure_level == "High"),
  `Moderate exposure organisms` = sum(exposure_risk$Exposure_level == "Moderate"),
  `Low exposure organisms` = sum(exposure_risk$Exposure_level == "Low"),
  `Mean exposure score` = round(mean(exposure_risk$Exposure_score, na.rm = TRUE), 3),
  `Median exposure score` = round(median(exposure_risk$Exposure_score, na.rm = TRUE), 3)
)

cat("\nSUMMARY STATISTICS:\n")
for(i in seq_along(exposure_stats)) {
  cat(names(exposure_stats)[i], ":", exposure_stats[[i]], "\n")
}

 # Graph : Top 10 most exposed organisms
top_10 <- head(exposure_risk, 10)

p <- ggplot(top_10, aes(x = reorder(Non_target_organism, Exposure_score),
                         y = Exposure_score, fill = Exposure_level)) +
  geom_col() +
  coord_flip() +
  scale_fill_manual(values = c("Low" = "#529985", "Moderate" = "#fdae61", 
                               "High" = "#d73027", "Very High" = "#9C0824")) +
  labs(
    title = paste("Most exposed NON-TARGET ORGANISMS\nTarget species suppression:", target_species),
    x = "",
    y = "Exposure score",
    fill = "Exposure level"
  ) +
  theme_minimal(base_size = 14, colour="black")

# Affiche dans la fenêtre Plot
print(p)

# Sauvegarde en TIFF 300 dpi
tiff("Top10_Exposure2_300dpi.tif", width = 8, height = 6, units = "in", res = 300)
print(p)
dev.off()


install.packages("ggtext")
library(ggtext)

# Graph : Top 10 most exposed organisms
top_10 <- head(exposure_risk, 10)

p <- ggplot(top_10, aes(x = reorder(Non_target_organism, Exposure_score),
                        y = Exposure_score, fill = Exposure_level)) +
  geom_col() +
  coord_flip() +
  scale_fill_manual(values = c("Low" = "#529985", "Moderate" = "#fdae61", 
                               "High" = "#d73027", "Very High" = "#9C0824")) +
  labs(
    title = paste("Most exposed NON-TARGET ORGANISMS\nTarget species suppression:", target_species),
    x = "",
    y = "Exposure score",
    fill = "Exposure level"
  ) +
  theme_minimal(base_size = 14) +
  theme(
    axis.text = element_text(color = "black", size = 12),      # axes en noir
    axis.title = element_text(color = "black", size = 14),     # titres axes
    plot.title = element_text(color = "black", size = 16)      # titre graphique
  )

# Affiche dans la fenêtre Plot
print(p)

# Sauvegarde en TIFF 300 dpi
tiff("Top10_Exposure2_300dpi.tif", width = 8, height = 6, units = "in", res = 300)
print(p)
dev.off()


