---
title: "Proactive Conservation Index tutorial"
author: "Gabriel Caetano"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Proactive Conservation Index tutorial}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

This tutorial teaches how to install and use package 'pciR', which calculates the Proactive Conservation Prioritization Index, a conservation priority index focused on the future. PCI is an easy to calculate index to prioritize species for conservation, which is flexible enough to incorporate any threat correlate. It also allows modulating the effects of threats using other variables such as species traits. PCI's rationale, methods, applications and guidelines are presented in the publication 'The future-focused Proactive Conservation Index highlights unrecognized global priorities for vertebrate conservation' (Caetano et al. 2025). A Shiny app to explore the results of this paper and the effects of different weighting schemes on PCI scores for global vertebrates can be found at: gabrielhoc.shinyapps.io/pci_app

# Vertebrate traits and threats data set

'PCI' includes a data set on threat correlates and traits for 33565 global vertebrate species, see (Caetano et al. 2025 for sources and descriptions of all data columns). The functions in the package can be used with any data set, not only the one included here. You can access the global vertebrate data using the command below:

```{r}
data("vert_df", package = "pciR")

head(vert_df)
```

You can see above that this data set contains the vertebrate species names ('binomial'); their taxonomic class ('class'); their taxonomic family ('family'); their threat category on the IUCN Red List of Threatened Species ('iucn_cat'); their maximum body mass, in grams ('body_mass'); their maximum brood size ('brood_size'); the area of their distribution range, in km2 ('range_area'); an index of how sensitive the species is to human-made habitats ('AHI'); the average human population density across the species range in four future scenarios ('popdens_2050_245', 'popdens_2050_585', 'popdens_2100_245', 'popdens_2100_585'); the proportion  of the species range lost due to climate change in four future scenarios ('clim_2050_245', 'clim_2100_245', 'clim_2050_585', 'clim_2100_585'); the proportion of the species range lost due to land use change in four future scenarios ('landuse_2050_245', 'landuse_2100_245', 'landuse_2050_585', 'landuse_2100_585') the proportion of the species range under high threat of biological invasions in 2100 ('inv_threat').

Some of these variables represent threats to species conservation (human population density, climate change, land use change, biological invasions), while others represent species characteristics that might make them more or less vulnerable to those threats (body mass, brood size, range size, protected area, AHI). Some variables such as range area, brood size and protected area are negatively associated with conservation priority To calculate the index, all variables must have the same direction (i.e. higher values are associated with higher extinction risk) so we must invert these variables:

```{r}
vert_df$log_body_mass <- log(vert_df$body_mass)
vert_df$inv_range_area <- 1/vert_df$range_area
vert_df$inv_brood_size <- 1/vert_df$brood_size
vert_df$inv_protected_area <- 1/((vert_df$protected_area*vert_df$range_area+0.0001)) #add small number to avoid division by zero
```

We will divide variables into two classes, extrinsic and intrinsic variables. Extrinsic variables refer to the threatening processes themselves, while intrinsic variables are characteristics of species that modulate their response to external threats. First we check the column names in our data table, so we can choose the variables we want.

```{r}
traits_vertebrates <-
   vert_df[c("log_body_mass",
             "inv_range_area",
             "inv_brood_size",
             "inv_protected_area",
             "AHI")]
```

We are going to calculate PCI for four different future scenarios (years 2050 and 2100 under carbon emission scenarios SSP 2.45 and SSP 5.85). Therefore we need to create separate data frames containing the extrinsic variables for each scenario. We want columns 7 and 8 for all scenarios (human_footprint and human population density), plus the columns for climate change (columns 9 to 12) and land use change (columns 13 to 16) corresponding to each scenario.

```{r}
threats_2050_245 <-
   vert_df[c("clim_2050_245",
             "landuse_2050_245",
             "popdens_2050_245",
             "inv_threat")]

threats_2050_585 <-
   vert_df[c("clim_2050_585",
             "landuse_2050_585",
             "popdens_2050_585",
             "inv_threat")]

threats_2100_245 <-
   vert_df[c("clim_2100_245",
             "landuse_2100_245",
             "popdens_2100_245",
             "inv_threat")]

threats_2100_585 <-
   vert_df[c("clim_2100_585",
             "landuse_2100_585",
             "popdens_2100_585",
             "inv_threat")]
```

# Calculating PCI

 We will output the top PCI scores for the top 6 species in each scenario, as well as the distribution of the index against its rank.

```{r}
vert_pci_2050_45 <-
  pciR::pci(sp = vert_df$binomial,
           var_out = threats_2050_245,
           var_in = traits_vertebrates)

head(vert_pci_2050_45[order(vert_pci_2050_45$rank),])
```

```{r}
vert_pci_2050_85 <-
  pciR::pci(sp = vert_df$binomial,
           var_out = threats_2050_585,
           var_in = traits_vertebrates)

head(vert_pci_2050_85[order(vert_pci_2050_85$rank),])
```

```{r}
vert_pci_2100_45 <-
  pciR::pci(sp = vert_df$binomial,
           var_out = threats_2100_245,
           var_in = traits_vertebrates)

head(vert_pci_2100_45[order(vert_pci_2100_45$rank),])
```

```{r}
vert_pci_2100_85 <-
  pciR::pci(sp = vert_df$binomial,
           var_out = threats_2100_585,
           var_in = traits_vertebrates)

head(vert_pci_2100_85[order(vert_pci_2100_85$rank),])
```

# Weighting

PCI allows users to assign custom weights to threats, and to the interactions between threats and species traits. Using this tool, users can adjust PCI to emphasize threats or traits more relevant to their taxa or region of interest. Weights must be input in the same order as the variables they are meant to weight. 

We are going to use arbitrary weights only to exemplify the functions working. Users should base their weighting system on previous evidence about the relative effect of threats in a given taxonomic group or region, or use an analytical method to derive weights empirically (we demonstrate an example of such a method below, and expand more on this topic in Caetano et al. 2025). In this example, we will assign a weight of 3 to climate change, 2 to land use change, 1 to human population density and 0 to biological invasions.

```{r}
names(threats_2100_585)
# [1] "clim_2100_245"    "landuse_2100_245" "popdens_2100_245" "inv_threat"      

weights_threats <- c(3, 2, 1, 0)
```

The weights for interactions between threats and traits must be input as a matrix, with a number of rows equal to the number of threats and a number of columns equal to the number of traits. Let's first create a matrix with all weights equal to 1, to figure out the position of each interaction.

```{r}
names(traits_vertebrates)
# [1] "log_body_mass"      "inv_range_area"     "inv_brood_size"     "inv_protected_area" "AHI"      

weights_traits <-
matrix(1, 
       ncol(threats_2100_585), 
       ncol(traits_vertebrates))

rownames(weights_traits) <- names(threats_2100_585)
colnames(weights_traits) <- names(traits_vertebrates)

weights_traits
```

We can, for example, change the weights of the interactions between body mass and with all threats to 2, and the weights of the interactions of range area with climate change and land use change to 3.

```{r}
# climate change, all rows
weights_traits[,1] <- 2

# land use change, first two rows
weights_traits[1,2] <- 3
weights_traits[2,2] <- 3

weights_traits
```

We can now use the new weights to recalculate PCI for all species in the year 2100, under scenario SSP 5.85.

```{r}
vert_pci_2100_85_weighted <-
  pciR::pci(sp = vert_df$binomial,
           var_out = threats_2100_585,
           var_in = traits_vertebrates,
           weight_out = weights_threats,
           weight_in = weights_traits)

head(vert_pci_2100_85_weighted[order(vert_pci_2100_85_weighted$rank),])
```

# Weight optimization

So far, we have used arbitrary weights as examples. However, the PCI package includes a function ('optim_weights') that allows the estimation of weights so PCI matches an external reference. This is useful, for example, if another conservation prioritization scheme is available for a subset of the species in the taxonomic group or region of interest, then this subset can be used to estimate the weights, which can then be applied to calculate PCI for the entire set of species.

For this example, we are going to use IUCN Red List categories as our reference, but users should refer to Caetano et al. 2025 for an extended comparison between PCI and the Red List. First, let's select only the subset of species that were assigned Red List categories that can be used in conservation prioritization schemes ('LC', 'NT', 'VU', 'EN', and 'CR'), then convert the categories into ordinate integers, with value increasing from less threatened to more threatened. We will also select only reptile species for this example, to reduce computation time, as the weight optimization function can take a while to run on larger data sets.

```{r}
rept_df <-
vert_df[vert_df$class == "Reptile",]

rept_df_iucn <-
  rept_df[rept_df$iucn_cat %in% 
            c("LC", "NT", "VU", "EN", "CR"),]

rept_df_iucn$iucn_cat_num <- 
  as.numeric(factor(rept_df_iucn$iucn_cat, 
         levels = c("LC", "NT", "VU", "EN", "CR")))
```

We must also subset the threat and trait data so it contains the same species as our weight calibration data set.

```{r}
threats_2100_585_rept_iucn <- 
threats_2100_585[vert_df$binomial %in% rept_df_iucn$binomial,]

traits_rept_iucn <-
traits_vertebrates[vert_df$binomial %in% rept_df_iucn$binomial,]
```

Now we can calibrate our weights, inputting the subsets of threat and trait data and the IUCN calibration reference. The function also allows the user to choose if they want to optimize weights only for threat variables ("out"), for threat/trait interactions ("in") or both ("both"). The optimization function then tries to find the set of weights that leads to the maximum correlation between PCI and the reference.

```{r}
optim_weights_rept <-
  pciR::optim_weights(sp = rept_df_iucn$binomial,
                     var_out = threats_2100_585_rept_iucn,
                     var_in = traits_rept_iucn,
                     reference = rept_df_iucn$iucn_cat_num,
                     type = "both",
                     control = list(maxit = 5))
```

We can now check the results of the weight optimization.

```{r}
optim_weights_rept$weight_out
optim_weights_rept$weight_in
```

And finally apply these weights to calculate PCI for all reptiles.

```{r}
threats_2100_585_rept <- 
threats_2100_585[vert_df$class == "Reptile",]

traits_rept <-
traits_vertebrates[vert_df$class == "Reptile",]

rept_pci_2100_85_opt <-
  pciR::pci(sp = rept_df$binomial,
           var_out = threats_2100_585_rept,
           var_in = traits_rept,
           weight_out = optim_weights_rept$weight_out,
           weight_in = optim_weights_rept$weight_in)

head(rept_pci_2100_85_opt[order(rept_pci_2100_85_opt$rank),])
```
