Overview

This vignette illustrates the basic usage of the raptr R package.

To load the raptr R package and learn more about the package, type the following code into R.

# load raptr R package
library(raptr)

# show package overview
?raptr

The raptr R package uses a range of S4 classes to store conservation planning data, parameters, and prioritisations (Table 1).

Table 1: Main classes in the raptr R package

Class Description
ManualOpts place-holder class for manually specified solutions
GurobiOpts stores parameters for solving optimisation problems using Gurobi
RapUnreliableOpts stores control variables parameters for the unreliable problem formulation
RapReliableOpts stores control variables for the reliable problem formulation
DemandPoints stores the coordinates and weights for a given species and attribute space
PlanningUnitPoints stores the coordinates and ids for planning units that can be used to preserve a given species
AttributeSpace stores the coordinates for planning units and the demand points for each species
RapData stores the all the planning unit, species, and attribute space data
RapUnsolved stores all the data, control variables, and parameters needed to generate prioritisations
RapResults stores the prioritisations and summary statistics generated after solving a problem
RapSolved stores the input data and output results

Getting started

This tutorial is designed to provide users with an understanding of how to use the raptr R package to generate and compare solutions. This tutorial uses several additional packages, so first we will run the following code to load them.

# load packages for tutorial
library(parallel)
library(plyr)
library(dplyr)
library(ggplot2)
library(RandomFields)
library(rgeos)

# set seed for reproducibility
set.seed(500)

# set number of threads for computation
threads <- as.integer(max(1, detectCores()-2))

Simulated examples

Data

To investigate the behaviour of the problem, we will generate prioritisations for three simulated species. We will use the unreliable formulation of the problem to understand the basics, and later move onto the reliable formulation. The first species (termed ‘uniform’) will represent a hyper-generalist. This species will inhabit all areas with equal probability. The second species (termed ‘normal’) will represent a species with a single range core. The third species (termed ‘bimodal’) will represent a species with two distinct ecotypes, each with their own range core. To reduce computational time for this example, we will use a 10 \(\times\) 10 grid of square planning units.

# make planning units
sim_pus <- sim.pus(100L)

# simulate species distributions
sim_spp <- lapply(
    c('uniform', 'normal', 'bimodal'),
    sim.species,
    n=1,
    x=sim_pus,
    res=1
)

Let’s see what these species’ distributions look like.

# plot species
plot(
    stack(sim_spp),
    main=c('Uniform species','Normal species','Bimodal species'),
    addfun=function(){lines(sim_pus)},
    nc=3
)
Distribution of three simulated species. Each square represents a planning unit. The colour of each square denotes the probability that individuals from each species occupy it.

Distribution of three simulated species. Each square represents a planning unit. The colour of each square denotes the probability that individuals from each species occupy it.

Next, we will generate a set of demand points. To understand the effects of probabilities and weights on the demand points, we will generate the demand points in geographic space. These demand points will be the centroids of the planning units. Additionally, we will use the same set of demand points for each species and only vary the weights of the demand points between species. Note that we are only using the same distribution of demand points for different species for teaching purposes. It is strongly recommended to use different demand points for different species in real-world conservation planning exercises. See the case-study section of this tutorial for examples on how to generate suitable demand points.

# generate coordinates for pus/demand points
pu_coords <- gCentroid(sim_pus, byid=TRUE)

# calculate weights
sim_dps <- lapply(
    sim_spp,
    function(x) {
        return(extract(x, pu_coords))
    }
)

# create demand point objects
sim_dps <- lapply(
    sim_dps,
    function(x) {
        return(
            DemandPoints(
                pu_coords@coords,
                weights=c(x)
            )
        )
    }
)

Now, we will construct a RapUnsolved object to store our input data and parameters. This contains all the information to generate prioritisations.

## create RapUnreliableOpts object
# this stores parameters for the unreliable formulation problem (ie. BLM)
sim_ro <- RapUnreliableOpts()

## create RapData object
# create data.frame with species info
species <- data.frame(
    name=c('uniform', 'normal', 'bimodal')
)

## create data.frame with species and space targets
# amount targets at 20% (denoted with target=0)
# space targets at 20% (denoted with target=1)
targets <- expand.grid(
    species=1:3,
    target=0:1,
    proportion=0.2
)

# calculate probability of each species in each pu
pu_probabilities <- calcSpeciesAverageInPus(sim_pus, stack(sim_spp))

## create AttributeSpace object
# this stores the coordinates of the planning units in an attribute space
# and the coordinates and weights of demand points in the space

pu_points <- PlanningUnitPoints(
    coords=pu_coords@coords,
    ids=seq_len(nrow(sim_pus@data))
)

attr_spaces <- AttributeSpaces(
    list(
        AttributeSpace(
            planning.unit.points=pu_points,
            demand.points=sim_dps[[1]],
            species=1L
        ),
        AttributeSpace(
            planning.unit.points=pu_points,
            demand.points=sim_dps[[2]],
            species=2L
        ),
        AttributeSpace(
            planning.unit.points=pu_points,
            demand.points=sim_dps[[3]],
            species=3L
        )
    ),
    name='geographic'
)

# generate boundary data information
boundary <- calcBoundaryData(sim_pus)

## create RapData object
# this stores all the input data for the prioritisation
sim_rd <- RapData(
    sim_pus@data,
    species,
    targets,
    pu_probabilities,
    list(attr_spaces),
    boundary,
    SpatialPolygons2PolySet(sim_pus)
)

## create RapUnsolved object
# this stores all the input data and parameters needed to generate prioritisations
sim_ru <- RapUnsolved(sim_ro, sim_rd)

Single-species prioritisations

Amount-based targets

To investigate the effects of space-based targets, we will generate a prioritisation for each species using only amount-based targets and compare them to prioritisations generated using amount- and space-based targets. To start off, we will generate a prioritisation for the uniform species using amount-based targets. To do this, we will generate a new sim_ru object by subsetting out the data for the uniform species from the sim_ru object. Then, we will update the targets in the new object. Finally, we will solve the object to generate a prioritisation that fulfills the targets for minimal cost.

# create new object with just the uniform species
sim_ru_s1 <- spp.subset(sim_ru, 'uniform')

# update amount targets to 20% and space targets to 0%
sim_ru_s1 <- update(sim_ru_s1, amount.target=0.2, space.target=NA, solve=FALSE)
# solve problem to identify prioritisation
sim_rs_s1_amount <- solve(sim_ru_s1, Threads=threads)
## Optimize a model with 1 rows, 100 columns and 100 nonzeros
## Variable types: 0 continuous, 100 integer (100 binary)
## Coefficient statistics:
##   Matrix range     [5e-01, 5e-01]
##   Objective range  [1e+00, 1e+00]
##   Bounds range     [1e+00, 1e+00]
##   RHS range        [1e+01, 1e+01]
## Found heuristic solution: objective 20
## Presolve removed 1 rows and 100 columns
## Presolve time: 0.00s
## Presolve: All rows and columns removed
## 
## Explored 0 nodes (0 simplex iterations) in 0.00 seconds
## Thread count was 1 (of 24 available processors)
## 
## Solution count 1: 20 
## Pool objective bound 20
## 
## Optimal solution found (tolerance 1.00e-01)
## Best objective 2.000000000000e+01, best bound 2.000000000000e+01, gap 0.0000%
## Warning in validityMethod(object): object@space.held contains values less
## than 0, some species are really poorly represented
## show summary
# note the format for this is similar to that used by Marxan
# see ?raptr::summary for details on this table
summary(sim_rs_s1_amount)
##   Run_Number  Status Score Cost Planning_Units Connectivity_Total
## 1          1 OPTIMAL    20   20             20                220
##   Connectivity_In Connectivity_Edge Connectivity_Out
## 1              42               168               10
##   Connectivity_In_Fraction
## 1                0.1909091
# show amount held
amount.held(sim_rs_s1_amount)
##   uniform
## 1     0.2
# show space held
space.held(sim_rs_s1_amount)
##   uniform (Space 1)
## 1        -0.2363636

Now that we have generated a prioritisation, let’s see what it looks like. We can use the spp.plot method to see how the prioritisation overlaps with the uniform species’ distribution. Note that since all planning units have equal probabilities for this species, all planning units have the same fill colour.

# plot the prioritisation and the uniform species' distribution
spp.plot(sim_rs_s1_amount, 1, main='Uniform species')

_A prioritisation for the uniformly distributed species generated using amount-based targets (20\%). Sqaures represent planning units. Planning units with a green border are selected for prioritisation, and their colour denotes the probability they are inhabited by the species._

The prioritisation for the uniform species appears to be just a random selection of planning units. This behavior is due to the fact that any prioritisation with 20 planning units is optimal. By relying on just amount targets, this solution may preserve a section of the species’ range core, or just focus on the range margin, or some random part of its range–no emphasis is directed towards preserving different parts of the species’ range. This behavior highlights a fundamental limitation of just using amount-based targets. In the absence of additional criteria, conventional reserve selection problems do not contain any additional information to identify the most effective prioritisation.

Now, we will generate a prioritisation for the normally distributed species using amount-based targets. We will use a similar process to what we used for the uniformly distributed species, but for brevity, we will use code to generate solutions immediately after updating the object.

# create new object with just the normal species
sim_ru_s2 <- spp.subset(sim_ru, 'normal')
# update amount targets to 20% and space targets to 0% and solve it
sim_rs_s2_amount <- update(sim_ru_s2, amount.target=0.2, space.target=NA, solve=TRUE, Threads=threads)
## Optimize a model with 1 rows, 100 columns and 100 nonzeros
## Variable types: 0 continuous, 100 integer (100 binary)
## Coefficient statistics:
##   Matrix range     [7e-02, 7e-01]
##   Objective range  [1e+00, 1e+00]
##   Bounds range     [1e+00, 1e+00]
##   RHS range        [7e+00, 7e+00]
## Found heuristic solution: objective 27
## Presolve removed 0 rows and 86 columns
## Presolve time: 0.00s
## Presolved: 1 rows, 14 columns, 14 nonzeros
## Variable types: 0 continuous, 14 integer (0 binary)
## Presolved: 1 rows, 14 columns, 14 nonzeros
## 
## 
## Root relaxation: objective 9.864476e+00, 6 iterations, 0.00 seconds
## 
##     Nodes    |    Current Node    |     Objective Bounds      |     Work
##  Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time
## 
##      0     0    9.86448    0    1   27.00000    9.86448  63.5%     -    0s
## H    0     0                      10.0000000    9.86448  1.36%     -    0s
## 
## Explored 0 nodes (6 simplex iterations) in 0.00 seconds
## Thread count was 22 (of 24 available processors)
## 
## Solution count 2: 10 27 
## Pool objective bound 10
## 
## Optimal solution found (tolerance 1.00e-01)
## Best objective 1.000000000000e+01, best bound 1.000000000000e+01, gap 0.0000%
# show summary
summary(sim_rs_s2_amount)
##   Run_Number  Status Score Cost Planning_Units Connectivity_Total
## 1          1 OPTIMAL    10   10             10                220
##   Connectivity_In Connectivity_Edge Connectivity_Out
## 1              12               192               16
##   Connectivity_In_Fraction
## 1               0.05454545
# show amount held
amount.held(sim_rs_s2_amount)
##      normal
## 1 0.2026153
# show space held
space.held(sim_rs_s2_amount)
##   normal (Space 1)
## 1        0.5909494

Now let’s visualise the prioritisation we made for the normal species.

# plot the prioritisation and the normal species' distribution
spp.plot(sim_rs_s2_amount, 1, main='Normal species')

_A prioritisation for the normally distributed species generated using amount-based targets (20\%). See Figure 3 caption for conventions._

The amount-based prioritisation for the normal species focuses only on the species’ range core. This prioritisation fails to secure any peripheral parts of the species’ distribution. As a consequence, it may miss out on populations with novel adaptations to environmental conditions along the species’ range margin.

Now, let’s generate an amount-based target for the bimodally distributed species view it.

# create new object with just the bimodal species
sim_ru_s3 <- spp.subset(sim_ru, 'bimodal')
# update amount targets to 20% and space targets to 0% and solve it
sim_rs_s3_amount <- update(sim_ru_s3, amount.target=0.2, space.target=NA, Threads=threads)
## Optimize a model with 1 rows, 100 columns and 100 nonzeros
## Variable types: 0 continuous, 100 integer (100 binary)
## Coefficient statistics:
##   Matrix range     [7e-03, 9e-01]
##   Objective range  [1e+00, 1e+00]
##   Bounds range     [1e+00, 1e+00]
##   RHS range        [7e+00, 7e+00]
## Found heuristic solution: objective 21
## Presolve removed 0 rows and 75 columns
## Presolve time: 0.00s
## Presolved: 1 rows, 25 columns, 25 nonzeros
## Variable types: 0 continuous, 25 integer (0 binary)
## Presolved: 1 rows, 25 columns, 25 nonzeros
## 
## 
## Root relaxation: objective 7.919039e+00, 17 iterations, 0.00 seconds
## 
##     Nodes    |    Current Node    |     Objective Bounds      |     Work
##  Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time
## 
##      0     0    7.91904    0    1   21.00000    7.91904  62.3%     -    0s
## H    0     0                       8.0000000    7.91904  1.01%     -    0s
## 
## Explored 0 nodes (17 simplex iterations) in 0.00 seconds
## Thread count was 22 (of 24 available processors)
## 
## Solution count 2: 8 21 
## Pool objective bound 8
## 
## Optimal solution found (tolerance 1.00e-01)
## Best objective 8.000000000000e+00, best bound 8.000000000000e+00, gap 0.0000%
# plot the prioritisation and the bimodal species' distribution
spp.plot(sim_rs_s3_amount, 1, main='Bimodal species')

_A prioritisation for the bimodally distributed species generated using amount-based targets (20\%). See Figure 3 caption for conventions._

# show summary
summary(sim_rs_s3_amount)
##   Run_Number  Status Score Cost Planning_Units Connectivity_Total
## 1          1 OPTIMAL     8    8              8                220
##   Connectivity_In Connectivity_Edge Connectivity_Out
## 1               9               197               14
##   Connectivity_In_Fraction
## 1               0.04090909
# show amount held
amount.held(sim_rs_s3_amount)
##     bimodal
## 1 0.2018391
# show space held
space.held(sim_rs_s3_amount)
##   bimodal (Space 1)
## 1         0.1200278

The amount-based prioritisation for the bimodally distributed species only selects planning units in the bottom left corner of the study area. This prioritisation only preserves individuals belonging to one of the two ecotypes. As a consequence, this prioritisation may fail to preserve a representative sample of the genetic variation found inside this species.

Amount-based and space-based targets

Now that we have generated a prioritisation for each species using only amount-based targets, we will generate a prioritisations using both amount-based and space-targets. To do this we will update the space targets in our amount-based prioritisations to 85%, and store the new prioritisations in new objects.

First, let’s do this for the uniform species.

# make new prioritisation
sim_rs_s1_space <- update(sim_rs_s1_amount, amount.target=0.2, space.target=0.85, Threads=threads)
## Warning for adding variables: zero or small (< 1e-13) coefficients, ignored
## Optimize a model with 10102 rows, 10100 columns and 40000 nonzeros
## Variable types: 0 continuous, 10100 integer (10100 binary)
## Coefficient statistics:
##   Matrix range     [5e-01, 8e+01]
##   Objective range  [1e+00, 1e+00]
##   Bounds range     [1e+00, 1e+00]
##   RHS range        [1e+00, 1e+02]
## Found heuristic solution: objective 90
## Presolve removed 36 rows and 0 columns
## Presolve time: 2.33s
## Presolved: 10066 rows, 10100 columns, 40104 nonzeros
## Variable types: 0 continuous, 10100 integer (10100 binary)
## Presolved: 10066 rows, 10100 columns, 40104 nonzeros
## 
## Presolve removed 10066 rows and 10100 columns
## 
## Root relaxation: objective 2.000000e+01, 572 iterations, 0.09 seconds
## 
##     Nodes    |    Current Node    |     Objective Bounds      |     Work
##  Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time
## 
## *    0     0               0      20.0000000   20.00000  0.00%     -    2s
## 
## Explored 0 nodes (893 simplex iterations) in 2.52 seconds
## Thread count was 22 (of 24 available processors)
## 
## Solution count 2: 20 90 
## Pool objective bound 20
## 
## Optimal solution found (tolerance 1.00e-01)
## Best objective 2.000000000000e+01, best bound 2.000000000000e+01, gap 0.0000%
# show summary
summary(sim_rs_s1_space)
##   Run_Number  Status Score Cost Planning_Units Connectivity_Total
## 1          1 OPTIMAL    20   20             20                220
##   Connectivity_In Connectivity_Edge Connectivity_Out
## 1              11               145               64
##   Connectivity_In_Fraction
## 1                     0.05
# show amount held
amount.held(sim_rs_s1_space)
##   uniform
## 1     0.2
# show space held
space.held(sim_rs_s1_space)
##   uniform (Space 1)
## 1         0.9242424

Let’s take a look at the prioritisation for the uniform species with amount-based and space-based targets. Then, let’s compare the solutions for the amount-based prioritisation with the new prioritisation using both amount and space targets.

# plot the prioritisation and the uniform species' distribution
spp.plot(sim_rs_s1_space, 'uniform', main='Uniform species')

_A prioritisation for the uniformly distributed species generated using amount-based targets (20\%) and space-based targets (85\%). See Figure 3 caption for conventions._

# plot the difference between old and new prioritisations
plot(sim_rs_s1_amount, sim_rs_s1_space, 1, 1, main='Difference between solutions')

_Difference between two prioritisations for the uniformly distributed species. Prioritisation $X$ was generated using just amount-based targets (20\%), and prioritisation $Y$ was generated using an additional space-based target (85\%)._

Here we can see that by including a space-target, the prioritisation is spread out evenly across the species’ distribution. Unlike the amount-based prioritisation, this prioritisation samples all the different parts of the species’ distribution.

Now, let’s generate a prioritisation for the normally distributed species that considers amount-based and space-based targets. Then, let’s visualise the new prioritisation and compare it to the old amount-based prioritisation.

# make new prioritisation
sim_rs_s2_space <- update(sim_rs_s2_amount, amount.target=0.2, space.target=0.85, Threads=threads)
## Warning for adding variables: zero or small (< 1e-13) coefficients, ignored
## Optimize a model with 10102 rows, 10100 columns and 40000 nonzeros
## Variable types: 0 continuous, 10100 integer (10100 binary)
## Coefficient statistics:
##   Matrix range     [7e-02, 4e+01]
##   Objective range  [1e+00, 1e+00]
##   Bounds range     [1e+00, 1e+00]
##   RHS range        [1e+00, 6e+01]
## Found heuristic solution: objective 90
## Presolve removed 220 rows and 0 columns
## Presolve time: 1.80s
## Presolved: 9882 rows, 10100 columns, 41664 nonzeros
## Variable types: 0 continuous, 10100 integer (10100 binary)
## Presolved: 9882 rows, 10100 columns, 41664 nonzeros
## 
## Presolve removed 9882 rows and 10100 columns
## 
## Root relaxation: objective 1.232570e+01, 4953 iterations, 0.34 seconds
## 
##     Nodes    |    Current Node    |     Objective Bounds      |     Work
##  Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time
## 
##      0     0   12.32570    0  292   90.00000   12.32570  86.3%     -    2s
## H    0     0                      13.0000000   12.32570  5.19%     -    2s
## 
## Explored 0 nodes (5189 simplex iterations) in 2.33 seconds
## Thread count was 22 (of 24 available processors)
## 
## Solution count 2: 13 90 
## Pool objective bound 13
## 
## Optimal solution found (tolerance 1.00e-01)
## Best objective 1.300000000000e+01, best bound 1.300000000000e+01, gap 0.0000%
# show summary
summary(sim_rs_s2_space)
##   Run_Number  Status Score Cost Planning_Units Connectivity_Total
## 1          1 OPTIMAL    13   13             13                220
##   Connectivity_In Connectivity_Edge Connectivity_Out
## 1               6               174               40
##   Connectivity_In_Fraction
## 1               0.02727273
# show amount held
amount.held(sim_rs_s2_space)
##      normal
## 1 0.2042594
# show space held
space.held(sim_rs_s2_space)
##   normal (Space 1)
## 1         0.854256
# plot the prioritisation and the normal species' distribution
spp.plot(sim_rs_s2_space, 'normal', main='Normal species')

_A prioritisation for the normally distributed species generated using amount-based targets (20\%) and space-based targets (85\%). See Figure 3 caption for conventions._

# plot the difference between old and new prioritisations
plot(sim_rs_s2_amount, sim_rs_s2_space, 1, 1, main='Difference between solutions')

_Difference between two prioritisations for the normally distributed species. See Figure 7 caption for conventions._

We can see by using both amount-based and space-based targets we can obtain a prioritisation that secures both the species’ range core and parts of its range margin. As a consequence, it may capture any novel adaptations found along the species’ range margin–unlike the amount-based prioritisation.

Finally, let’s generate a prioritisation for the bimodal species using amount-based and space-based targets.

# make new prioritisation
sim_rs_s3_space <- update(sim_rs_s3_amount, amount.target=0.2, space.target=0.85, Threads=threads)
## Warning for adding variables: zero or small (< 1e-13) coefficients, ignored
## Optimize a model with 10102 rows, 10100 columns and 40000 nonzeros
## Variable types: 0 continuous, 10100 integer (10100 binary)
## Coefficient statistics:
##   Matrix range     [7e-03, 9e+01]
##   Objective range  [1e+00, 1e+00]
##   Bounds range     [1e+00, 1e+00]
##   RHS range        [1e+00, 7e+01]
## Found heuristic solution: objective 85
## Presolve removed 589 rows and 15 columns
## Presolve time: 3.66s
## Presolved: 9513 rows, 10085 columns, 51461 nonzeros
## Variable types: 0 continuous, 10085 integer (10085 binary)
## Presolved: 9513 rows, 10085 columns, 51461 nonzeros
## 
## Presolve removed 9513 rows and 10085 columns
## 
## Root relaxation: objective 8.980792e+00, 5356 iterations, 0.42 seconds
## 
##     Nodes    |    Current Node    |     Objective Bounds      |     Work
##  Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time
## 
##      0     0    8.98079    0   75   85.00000    8.98079  89.4%     -    4s
## H    0     0                      10.0000000    8.98079  10.2%     -    4s
## 
## Explored 0 nodes (5644 simplex iterations) in 4.83 seconds
## Thread count was 22 (of 24 available processors)
## 
## Solution count 2: 10 85 
## Pool objective bound 10
## 
## Optimal solution found (tolerance 1.00e-01)
## Best objective 1.000000000000e+01, best bound 1.000000000000e+01, gap 0.0000%
# show summary
summary(sim_rs_s3_space)
##   Run_Number  Status Score Cost Planning_Units Connectivity_Total
## 1          1 OPTIMAL    10   10             10                220
##   Connectivity_In Connectivity_Edge Connectivity_Out
## 1               7               187               26
##   Connectivity_In_Fraction
## 1               0.03181818
# show amount held
amount.held(sim_rs_s3_space)
##     bimodal
## 1 0.2226414
# show space held
space.held(sim_rs_s3_space)
##   bimodal (Space 1)
## 1         0.8562891
# plot the prioritisation and the bimodal species' distribution
spp.plot(sim_rs_s3_space, 'bimodal', main='Bimodal species')

_A prioritisation for the normally distributed species generated using amount-based targets (20\%) and space-based targets (85\%). See Figure 3 caption for conventions._

# plot the difference between old and new prioritisations
plot(sim_rs_s3_amount, sim_rs_s3_space, 1, 1, main='Difference between solutions')

_Difference between two prioritisations for the bimodally distributed species. See Figure 7 caption for conventions._

Earlier we found that the amount-based prioritisation only preserved individuals from a single ecotype, and would have failed to adequately preserve the intra-specific variation for this species. However, here we can see that by including space-based targets, we can develop prioritisations that secure individuals belonging to both ecotypes. This new prioritisation is much more effective at sampling the intra-specific variation for this species.

Overall, these results demonstrate that under the simplest of conditions, the use of space-based targets can improve prioritisations. However, these prioritisations were each generated for a single species. Prioritisations generated using multiple species may do a better job at preserving the intra-specific variation for individuals species by preserving them in different parts of their range. We will investigate this in the next section.

Multi-species prioritisations

Effects of including space-based targets

So far we have generated prioritisations using only a single species at a time. However, real world prioritisations are often generated using multiple species to ensure that they preserve a comprehensive set of biodiversity. Here, we will generate multi-species prioritisations that preserve all three of the simulated species. First, we will generate a prioritisation using amount-based targets that only aims to preserve 20% of the area they occupy. Then, we will generate a prioritisation that also incoperate space-based targets to also preserve 85% of their geographic distribution. We will then compare the two prioritisations.

# make prioritisations
sim_mrs_amount <- update(
    sim_ru,
    amount.target=c(0.2,0.2,0.2),
    space.target=c(0,0,0),
    Threads=threads
)
## Warning for adding variables: zero or small (< 1e-13) coefficients, ignored
## Optimize a model with 30306 rows, 30100 columns and 120000 nonzeros
## Variable types: 0 continuous, 30100 integer (30100 binary)
## Coefficient statistics:
##   Matrix range     [7e-03, 9e+01]
##   Objective range  [1e+00, 1e+00]
##   Bounds range     [1e+00, 1e+00]
##   RHS range        [1e+00, 8e+02]
## Found heuristic solution: objective 96
## Presolve time: 2.02s
## Presolved: 30306 rows, 30100 columns, 120000 nonzeros
## Variable types: 0 continuous, 30100 integer (30100 binary)
## Presolved: 30306 rows, 30100 columns, 120000 nonzeros
## 
## Presolve removed 30306 rows and 30100 columns
## 
## Root relaxation: objective 2.000000e+01, 2719 iterations, 1.60 seconds
## 
##     Nodes    |    Current Node    |     Objective Bounds      |     Work
##  Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time
## 
## *    0     0               0      20.0000000   20.00000  0.00%     -    4s
## 
## Explored 0 nodes (5125 simplex iterations) in 4.09 seconds
## Thread count was 22 (of 24 available processors)
## 
## Solution count 2: 20 96 
## Pool objective bound 20
## 
## Optimal solution found (tolerance 1.00e-01)
## Best objective 2.000000000000e+01, best bound 2.000000000000e+01, gap 0.0000%
sim_mrs_space <- update(
    sim_ru,
    amount.target=c(0.2,0.2,0.2),
    space.target=c(0.85, 0.85, 0.85),
    Threads=threads
)
## Warning for adding variables: zero or small (< 1e-13) coefficients, ignored
## Optimize a model with 30306 rows, 30100 columns and 120000 nonzeros
## Variable types: 0 continuous, 30100 integer (30100 binary)
## Coefficient statistics:
##   Matrix range     [7e-03, 9e+01]
##   Objective range  [1e+00, 1e+00]
##   Bounds range     [1e+00, 1e+00]
##   RHS range        [1e+00, 1e+02]
## Found heuristic solution: objective 100
## Presolve removed 269 rows and 15 columns (presolve time = 5s) ...
## Presolve removed 360 rows and 15 columns
## Presolve time: 8.28s
## Presolved: 29946 rows, 30085 columns, 131504 nonzeros
## Variable types: 0 continuous, 30085 integer (30085 binary)
## Presolve removed 53 rows and 1 columns
## Presolved: 29893 rows, 30084 columns, 127236 nonzeros
## 
## Presolve removed 29893 rows and 30084 columns
## 
## Root simplex log...
## 
## Iteration    Objective       Primal Inf.    Dual Inf.      Time
##        0    1.0000000e+02   0.000000e+00   1.000000e+02      9s
##     4377    2.0000000e+01   0.000000e+00   0.000000e+00     10s
##     4377    2.0000000e+01   0.000000e+00   0.000000e+00     10s
## 
## Root relaxation: objective 2.000000e+01, 4377 iterations, 1.76 seconds
## 
##     Nodes    |    Current Node    |     Objective Bounds      |     Work
##  Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time
## 
##      0     0   20.00000    0  349  100.00000   20.00000  80.0%     -   11s
## H    0     0                      24.0000000   20.00000  16.7%     -   11s
## H    0     0                      20.0000000   20.00000  0.00%     -   11s
## 
## Explored 0 nodes (8538 simplex iterations) in 11.28 seconds
## Thread count was 22 (of 24 available processors)
## 
## Solution count 3: 20 24 100 
## Pool objective bound 20
## 
## Optimal solution found (tolerance 1.00e-01)
## Best objective 2.000000000000e+01, best bound 2.000000000000e+01, gap 0.0000%
# show summaries
summary(sim_mrs_amount)
##   Run_Number  Status Score Cost Planning_Units Connectivity_Total
## 1          1 OPTIMAL    20   20             20                220
##   Connectivity_In Connectivity_Edge Connectivity_Out
## 1               9               143               68
##   Connectivity_In_Fraction
## 1               0.04090909
summary(sim_mrs_space)
##   Run_Number  Status Score Cost Planning_Units Connectivity_Total
## 1          1 OPTIMAL    20   20             20                220
##   Connectivity_In Connectivity_Edge Connectivity_Out
## 1               8               144               68
##   Connectivity_In_Fraction
## 1               0.03636364
# show amount held for each prioritisation
amount.held(sim_mrs_amount)
##   uniform    normal   bimodal
## 1     0.2 0.2069044 0.2178603
amount.held(sim_mrs_space)
##   uniform    normal  bimodal
## 1     0.2 0.2255469 0.242757
# show space held for each prioritisation
space.held(sim_mrs_amount)
##   uniform (Space 1) normal (Space 1) bimodal (Space 1)
## 1         0.9090909        0.8634637         0.8923004
space.held(sim_mrs_space)
##   uniform (Space 1) normal (Space 1) bimodal (Space 1)
## 1         0.9290909        0.9108412         0.9326686
# plot multi-species prioritisation with amount-based targets
plot(sim_mrs_amount, 1, main='Amount-based targets')

_A multi-species prioritisation for the uniformly, normally, and bimodally distributed species generated using just amount-based targets (20\%). Squares represent planning units. Dark green planning units are selected for preservation._

# plot multi-species prioritisation with amount- and space-based targets
plot(sim_mrs_space, 1, main='Amount and space-based targets')

_A multi-species prioritisation for the uniformly, normally, and bimodally distributed species generated using amount-based targets (20\%) and space-based targets (85\%). See Figure 12 caption for conventions._

# difference between the two prioritisations
plot(sim_mrs_amount, sim_mrs_space, 1, 1, main='Difference between solutions')

_Difference between two multi-species prioritisations. See Figure 7 caption for conventions.)

Here we can see that the inclusion of space-based targets changes which planning units are selected for prioritisation, but also the number of planning units that are selected. The amount-based prioritisation is comprised of 20 units, and the space-based prioritisation is comprised of 20 units. This result suggests that an adequate and representative prioritisation can be achieved for only a minor increase in cost.

Uncertainty in species’ distributions

The unreliable formulation does not consider the probability that the planning units are occupied by features when calculating how well a given solution secures a representative sample of an attribute space. Thus solutions identified using the unreliable formulation may select regions of an attribute space for a species using planning units that only have a small chance of being inhabited. As a consequence, if the prioritisation is implemented, it may fail to secure regions of an attribute space if individuals do not inhabit these planning units, and ultimately fail to fulfil the space-based targets.

A simple solution to this issue would be to ensure that planning units cannot be assigned to demand points if they have a low probability of occupancy. This can be achieved by setting a probability threshold for planning units, such that planning units with a probability of occupancy below the threshold are effectively set to zero.

# make new prioritisation with probability threshold of 0.1 for each species
sim_mrs_space2 <- solve(
    prob.subset(
        sim_mrs_space,
        species=1:3,
        threshold=c(0.1,0.1,0.1)
    ),
    Threads=threads
)
## Warning for adding variables: zero or small (< 1e-13) coefficients, ignored
## Optimize a model with 30306 rows, 30100 columns and 119974 nonzeros
## Variable types: 0 continuous, 30100 integer (30100 binary)
## Coefficient statistics:
##   Matrix range     [7e-03, 9e+01]
##   Objective range  [1e+00, 1e+00]
##   Bounds range     [1e+00, 1e+00]
##   RHS range        [1e+00, 1e+02]
## Found heuristic solution: objective 100
## Presolve removed 269 rows and 15 columns (presolve time = 5s) ...
## Presolve removed 360 rows and 15 columns
## Presolve time: 8.15s
## Presolved: 29946 rows, 30085 columns, 131478 nonzeros
## Variable types: 0 continuous, 30085 integer (30085 binary)
## Presolve removed 53 rows and 1 columns
## Presolved: 29893 rows, 30084 columns, 127210 nonzeros
## 
## Presolve removed 29893 rows and 30084 columns
## 
## Root simplex log...
## 
## Iteration    Objective       Primal Inf.    Dual Inf.      Time
##        0    1.0000000e+02   0.000000e+00   1.000000e+02      9s
##     3270    2.4608976e+01   0.000000e+00   1.119228e+04     10s
##     4415    2.0000000e+01   0.000000e+00   0.000000e+00     11s
##     4415    2.0000000e+01   0.000000e+00   0.000000e+00     11s
## 
## Root relaxation: objective 2.000000e+01, 4415 iterations, 2.34 seconds
## 
##     Nodes    |    Current Node    |     Objective Bounds      |     Work
##  Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time
## 
##      0     0   20.00000    0    2  100.00000   20.00000  80.0%     -   11s
## H    0     0                      20.0000000   20.00000  0.00%     -   11s
## 
## Explored 0 nodes (9263 simplex iterations) in 11.57 seconds
## Thread count was 22 (of 24 available processors)
## 
## Solution count 2: 20 100 
## Pool objective bound 20
## 
## Optimal solution found (tolerance 1.00e-01)
## Best objective 2.000000000000e+01, best bound 2.000000000000e+01, gap 0.0000%
# show summary
summary(sim_mrs_space2)
##   Run_Number  Status Score Cost Planning_Units Connectivity_Total
## 1          1 OPTIMAL    20   20             20                220
##   Connectivity_In Connectivity_Edge Connectivity_Out
## 1               6               140               74
##   Connectivity_In_Fraction
## 1               0.02727273
# plot prioritisation
plot(sim_mrs_space2, 1)

_A multi-species prioritisation for the uniformly, normally, and bimodally distributed species generated using amount-based targets (20\%) and space-based targets (85\%). This priorititisation was generated to be robust against low occupancy probabilities, by preventing planning units with low probabilities from being used to represent demand points. See Figure 12 caption for conventions._

# difference between prioritisations that use and do not use thresholds
plot(sim_mrs_space2, sim_mrs_space, 1, 1, main='Difference between solutions')

_Difference between two multi-species prioritisations. See Figure 7 caption for conventions._

But this method requires setting somewhat arbitrary thresholds. A more robust solution to this issue is to actually use the probability that species occupy planning units to generate the prioritisations. This is what the reliable formulation does. First we will try and generate a solution using existing targets and the reliable formulation. To reduce computational time, we will set the maximum backup \(R\)-level to 1.

# make new prioritisation using reliable formulation
sim_mrs_space3 <- try(update(sim_mrs_space, formulation='reliable', max.r.level=1L, Threads=threads))
## Warning for adding variables: zero or small (< 1e-13) coefficients, ignored
## Optimize a model with 364206 rows, 181900 columns and 3847200 nonzeros
## Variable types: 0 continuous, 60700 integer (60700 binary)
## Semi-Variable types: 121200 continuous, 0 integer
## Coefficient statistics:
##   Matrix range     [8e-04, 1e+02]
##   Objective range  [1e+00, 1e+00]
##   Bounds range     [1e+00, 1e+00]
##   RHS range        [7e-03, 1e+02]
## Presolve removed 338603 rows and 156700 columns (presolve time = 5s) ...
## Presolve removed 338606 rows and 156703 columns
## Presolve time: 5.40s
## 
## Explored 0 nodes (0 simplex iterations) in 7.46 seconds
## Thread count was 1 (of 24 available processors)
## 
## Solution count 0
## Pool objective bound 1e+100
## 
## Model is infeasible
## Best objective -, best bound -, gap -

However, this fails. The reason why we cannot generate a prioritisation that fulfills these targets is because even the solution that contains all the planning units is still insufficient when we consider probabilities. The negative maximum targets printed in the error message indicate that planning units have low probabilities of occupancy. To fulfill the targets, we must obtain more planning units with higher probabilities of occupancy. We also could attempt resolving the problem using a higher \(R\)-level. Instead, we will set lower targets and generate solution.

# make new prioritisation using reliable formulation and reduced targets
sim_mrs_space3 <- update(
    sim_mrs_space,
    formulation='reliable',
    max.r.level=1L,
    space.target=-1000,
    Threads=threads
)
## Warning for adding variables: zero or small (< 1e-13) coefficients, ignored
## Optimize a model with 364206 rows, 181900 columns and 3847200 nonzeros
## Variable types: 0 continuous, 60700 integer (60700 binary)
## Semi-Variable types: 121200 continuous, 0 integer
## Coefficient statistics:
##   Matrix range     [8e-04, 1e+02]
##   Objective range  [1e+00, 1e+00]
##   Bounds range     [1e+00, 1e+00]
##   RHS range        [7e-03, 8e+05]
## Presolve removed 333403 rows and 151500 columns (presolve time = 5s) ...
## Presolve removed 333903 rows and 151800 columns
## Presolve time: 9.95s
## Presolved: 30303 rows, 30100 columns, 90300 nonzeros
## Variable types: 0 continuous, 30100 integer (30100 binary)
## Found heuristic solution: objective 27.0000000
## Presolved: 30303 rows, 30100 columns, 90300 nonzeros
## 
## Presolve removed 30303 rows and 30100 columns
## 
## Root simplex log...
## 
## Iteration    Objective       Primal Inf.    Dual Inf.      Time
##        0    1.0000000e+02   0.000000e+00   1.000000e+02     13s
##      129    2.0000000e+01   0.000000e+00   0.000000e+00     13s
##      129    2.0000000e+01   0.000000e+00   0.000000e+00     13s
## 
## Root relaxation: objective 2.000000e+01, 129 iterations, 0.46 seconds
## 
##     Nodes    |    Current Node    |     Objective Bounds      |     Work
##  Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time
## 
## *    0     0               0      20.0000000   20.00000  0.00%     -   13s
## 
## Explored 0 nodes (182 simplex iterations) in 13.15 seconds
## Thread count was 22 (of 24 available processors)
## 
## Solution count 2: 20 27 
## Pool objective bound 20
## 
## Optimal solution found (tolerance 1.00e-01)
## Best objective 2.000000000000e+01, best bound 2.000000000000e+01, gap 0.0000%
## Warning in validityMethod(object): object@space.held contains values less
## than 0, some species are really poorly represented
# show summary
summary(sim_mrs_space3)
##   Run_Number  Status Score Cost Planning_Units Connectivity_Total
## 1          1 OPTIMAL    20   20             20                220
##   Connectivity_In Connectivity_Edge Connectivity_Out
## 1              20               156               44
##   Connectivity_In_Fraction
## 1               0.09090909
# plot prioritisation
plot(sim_mrs_space3, 1)

_A multi-species prioritisation for the uniformly, normally, and bimodally distributed species generated using amount-based targets (20\%) and space-based targets (85\%). This priorititisation was generated to be robust against low occupancy probabilities, by explicitly using the probability of occupancy data when deriving a solution. See Figure 12 caption for conventions._

# difference between prioritisations based on unreliable and reliable formulation
plot(sim_mrs_space3, sim_mrs_space, 1, 1, main='Difference between solutions')

_Difference between two multi-species prioritisations. See Figure 7 caption for conventions._

An additional planning unit was selected using the reliable formulation. The prioritisation based on the unreliable formulation had 20 planning units, but the prioritisation based on the reliable formlation has 20 planning units. This difference occurs because the reliable formulation needs to ensure that all selected planning units with a low chance of being occupied have a suitable backup planning unit. While the reliable formulation can deliver more robust prioritisations, it takes much longer to solve conservation planning problems expressed using this formulation than the unreliable formulation. As a consequence, the reliable formulation is only feasible for particularly small problems, such as those involving few features and less than several hundred planning units.

Fragmentation

Fragmentation is an important consideration in real-world planning situations. Up until now, we haven’t considered the effects of fragmentation on the viability of the prioritisation. As a consequence, our prioritisations have tended to contain planning units without any neighbours. We can use the BLM parameter to penalise fragmented solutions.

Let’s generate a new prioritisation that heavily penalises fragmentation. Here, we will update the sim_mrs_amount object with BLM of 100.

# update prioritisation
sim_mrs_amount_blm <- update(sim_mrs_amount, BLM=100, Threads=threads)
## Warning for adding variables: zero or small (< 1e-13) coefficients, ignored
## Optimize a model with 30666 rows, 30280 columns and 120720 nonzeros
## Variable types: 0 continuous, 30280 integer (30280 binary)
## Coefficient statistics:
##   Matrix range     [7e-03, 9e+01]
##   Objective range  [1e+02, 4e+02]
##   Bounds range     [1e+00, 1e+00]
##   RHS range        [1e+00, 8e+02]
## Found heuristic solution: objective 4596
## Presolve time: 1.43s
## Presolved: 30666 rows, 30280 columns, 120720 nonzeros
## Variable types: 0 continuous, 30280 integer (30280 binary)
## Presolved: 30666 rows, 30280 columns, 120720 nonzeros
## 
## Presolve removed 30666 rows and 30280 columns
## 
## Root relaxation: objective 4.644444e+02, 4592 iterations, 3.37 seconds
## Total elapsed time = 5.05s
## 
##     Nodes    |    Current Node    |     Objective Bounds      |     Work
##  Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time
## 
##      0     0  464.44444    0 1725 4596.00000  464.44444  89.9%     -    5s
## H    0     0                    1621.0000000  464.44444  71.3%     -   15s
## H    0     0                    1336.0000000  464.44444  65.2%     -   16s
## H    0     0                    1335.0000000  464.44444  65.2%     -   16s
## H    0     0                    1232.0000000  464.44444  62.3%     -   16s
## H    0     0                    1122.0000000  464.44444  58.6%     -   16s
## H    0     0                    1120.0000000  464.44444  58.5%     -   16s
## H    0     0                    1022.0000000  464.44444  54.6%     -   17s
## H    0     0                    1021.0000000  464.44444  54.5%     -   17s
##      0     0  539.75309    0 1722 1021.00000  539.75309  47.1%     -   17s
## H    0     0                    1020.0000000  539.75309  47.1%     -   17s
##      0     0  539.75309    0 1722 1020.00000  539.75309  47.1%     -   17s
##      0     0  590.00000    0 1403 1020.00000  590.00000  42.2%     -   18s
##      0     0  590.00000    0 1409 1020.00000  590.00000  42.2%     -   19s
##      0     0  590.00000    0 1665 1020.00000  590.00000  42.2%     -   24s
##      0     0  590.00000    0 1665 1020.00000  590.00000  42.2%     -   25s
##      0     2  590.00000    0 1323 1020.00000  590.00000  42.2%     -   35s
##     53    76  663.06220    6 1439 1020.00000  657.64706  35.5%  1083   40s
##    219   194  743.61360   13 1372 1020.00000  667.59450  34.5%   621   45s
##    298   242  774.09836   15 1362 1020.00000  667.59450  34.5%   574   50s
## H  435   242                     920.0000000  680.60606  26.0%   559   54s
##    473   227  810.69767   20 1013  920.00000  686.99095  25.3%   574   55s
##    524   248  820.71174   21 1010  920.00000  693.26733  24.6%   574   63s
##    603   262     cutoff   23       920.00000  735.87302  20.0%   566   66s
##    738   276  903.58209    9 1310  920.00000  747.65957  18.7%   543   70s
##    948   252     cutoff   18       920.00000  786.66667  14.5%   526   76s
##   1124   225  905.02018    6 1366  920.00000  822.43902  10.6%   511   80s
## 
## Cutting planes:
##   Gomory: 2
##   Zero half: 361
## 
## Explored 1285 nodes (680185 simplex iterations) in 83.78 seconds
## Thread count was 22 (of 24 available processors)
## 
## Solution count 10: 920 1020 1021 ... 1621
## Pool objective bound 840
## 
## Optimal solution found (tolerance 1.00e-01)
## Best objective 9.200000000000e+02, best bound 8.400000000000e+02, gap 8.6957%
# show summary of prioritisation
summary(sim_mrs_amount_blm)
##   Run_Number  Status Score Cost Planning_Units Connectivity_Total
## 1          1 OPTIMAL   920   20             20                220
##   Connectivity_In Connectivity_Edge Connectivity_Out
## 1              36               171               13
##   Connectivity_In_Fraction
## 1                0.1636364
# show amount held for each prioritisation
amount.held(sim_mrs_amount_blm)
##   uniform    normal   bimodal
## 1     0.2 0.2328119 0.3427728
# show space held for each prioritisation
space.held(sim_mrs_amount_blm)
##   uniform (Space 1) normal (Space 1) bimodal (Space 1)
## 1         0.3333333        0.2755485         0.4585042
# plot prioritisation
plot(sim_mrs_amount_blm, 1)

_A multi-species prioritisation for the uniformly, normally, and bimodally distributed species generated using only amount-based targets (20\%). Additionally, this priorititisation was specified to have high connectivity, by using a high $BLM$ parameter. See Figure 12 caption for conventions._

# difference between the two prioritisations
plot(sim_mrs_amount_blm, sim_mrs_amount, 1, 1, main='Difference between solutions')

_Difference between two multi-species prioritisations. See Figure 7 caption for conventions._

Here we can see that the prioritisation generated using a BLM parameter of 100 is much more clustered than the prioritisation generated using a BLM of 0. In practice, conservation planners will need to try a variety of BLM parameters to find a suitable prioritisation.

Case-study examples

Introduction

Here we will investigate how space-based targets can affect prioritisations using a more realistic dataset. We will generate prioritisations for the four bird species– blue-winged kookaburra, brown-backed honeyeater, brown falcon, pale-headed rosella–in Queensland, Australia. This region contains a broad range of different habitats–such as rainforests, woodlands, and deserts–making it ideal for this tutorial. First, we will generate a typical amount-based prioritisation that aims to capture 20% of the species’ distributions. Then we will generate a prioritisation that also aims to secure populations in representative parts of the species’ distributions in terms of their geographic location and their environmental heterogeneity. To do this we will generate a prioritisation using 20% amount-based targets and 85% space-based targets. Finally, we will compare these prioritisations to Australia’s existing protected network.

Data

Survey data for the species were obtained from BirdLife Australia. The survey data was rarefied using a 100 km\(^2\) grid, wherein the survey with the greatest number of repeat visits in each grid cell was chosen. To model the distribution of each species, environmental data were obtained at survey location (site). Specifically, climatic data (bio1, bio4, bio15, bio16, bio17) and classifications of the vegetation at the site were used. Occupancy-detection models were fit using Stan using manually tuned parameters (adapt deta=0.9, maximum treedepth=20, chains=4 , warmup iterations=1000, total iterations=1500) with five-fold cross-validation. In each replicate, data were partitioned into training and test sites. A full model was fit using quadratic terms for environmental variables in the site-component, and an intercept in the detection-component of the model. The full model was then subject to a step-wise backwards term deletion routine. Terms were retained when their inclusion resulted in a model with a greater area under the curve (AUC) value as calculated using the test data. Maps were generated for each species as an average of the predictions from the best model in each best replicate. To further improve the accuracy of these maps, areas well outside of the species’ known distributions were set to 0. For each species, this was achieved by masking out biogeographic regions where the species was not observed, and regions that did not have a neighbouring planning unit where the species was observed. The maps were then resampled (10 km\(^2\) resolution) and cropped to the study area. The resulting maps are stored in the cs_spp object.

# load data
data(cs_spp)

# remove areas with low occupancy (prob < 0.6)
cs_spp[cs_spp<0.6] <- NA

# plot species' distributions
plot(cs_spp, main=c(
    "Blue-winged kookaburra", "Brown-backed honeyeater", 
    "Brown falcon", "Pale-headed rosella"
))

_Distribution map for four Australian bird species. Pixel colours denote probability of occupancy._

Planning units (50km\(^2\) resolution) were generated across Australia, and then clipped to the Queensland state borders and coastline. Note that we are using excessively coarse planning units so that our examples will complete relatively quickly. In a real-world planning exercise, we would use much finer planning units. To compare our prioritisations to Queensland’s existing protected area network, this network was intersected with the planning units. Planning units with more than 50% of their area inside a protected area had their status set to 2 (following conventions in Marxan). Since we do not have cost data, the prioritisations will aim to select the minimum number of planning units required to meet the targets. The planning units are stored in the cs_pu object.

# load data
data(cs_pus)

## plot planning units
# convert SpatialPolygons to PolySet for quick plotting
cs_pus2 <- SpatialPolygons2PolySet(cs_pus)

# create vector of colours for planning units
# + light green: units not already inside reserve
# + yellow: units already inside reserve
cs_pus_cols <- rep('#c7e9c0', nrow(cs_pus@data))
cs_pus_cols[which(cs_pus$status==2)] <- 'yellow'

# set plotting window
par(mar=c(0.1, 0.1, 4.1, 0.1))

# plot polygons
PBSmapping::plotPolys(
    cs_pus2, col=cs_pus_cols, border='gray30', 
    xlab='', ylab='', axes=FALSE, 
    main='Case-study planning units',
    cex=1.8
)

_Planning units for the case-study examples. Polygons denote planning units. Yellow units have more than 50\% of their area already in a reserve.)

# reset plotting window
par(mar=c(5.1, 4.1, 4.1, 2.1))

To map the distribution of environmental conditions across the species’ range, 21 bioclimatic layers were obtained. These layers were cropped to Australia and subject to detrended correspondence analysis to produce two new variables. These layers are stored in the cs_space object.

# load data
data(cs_space)

# plot variables
plot(cs_space, main=c('DC1', 'DC2'), legend=FALSE, axes=FALSE)

_Broad-scale environmental variation across Australia. The variable DC1 describes the transition from wet and cool to dry and hot conditions. The variable DC2 describes the transition from wet and hot to dry and cool conditions._

Analysis

To simplify the process of formatting data and generating prioritisations, we can use the rap function. First, we will generate an amount-based prioritisation that aims to capture 10% of the rosella’s range. We will use 50 demand points to map the geographic and environmental spaces. Be warned, the examples hereafter can take 5-10 minutes to run.

# make amount-based prioritisation
# and ignore existing protected areas by discarding values in the 
# status (third) column of the attribute table
cs_rs_amount <- rap(
    cs_pus[,-2], cs_spp, cs_space,
    amount.target=0.2, space.target=NA, n.demand.points=50L,
    include.geographic.space=TRUE, formulation='unreliable',
    kernel.method='hypervolume', quantile=0.7, solve=FALSE
)
## Warning in (function (pus, species, spaces = NULL, amount.target = 0.2, :
## argument to pus does not have a 'status' column, creating default with all
## status=0L
## Evaluating probability density...
## Building tree... done.
## Querying tree... 1.0101e-06  0.010102  0.020203  0.030304  0.0404051  0.0505061  0.0606071  0.0707081  0.0808091  0.0909101  0.101011  0.111112  0.121213  0.131314  0.141415  0.151516  0.161617  0.171718  0.181819  0.19192  0.202021  0.212122  0.222223  0.232324  0.242425  0.252526  0.262627  0.272728  0.282829  0.29293  0.303031  0.313132  0.323233  0.333334  0.343435  0.353536  0.363637  0.373738  0.383839  0.39394  0.404041  0.414142  0.424243  0.434344  0.444445  0.454546  0.464647  0.474748  0.484849  0.494951  0.505052  0.515153  0.525254  0.535355  0.545456  0.555557  0.565658  0.575759  0.58586  0.595961  0.606062  0.616163  0.626264  0.636365  0.646466  0.656567  0.666668  0.676769  0.68687  0.696971  0.707072  0.717173  0.727274  0.737375  0.747476  0.757577  0.767678  0.777779  0.78788  0.797981  0.808082  0.818183  0.828284  0.838385  0.848486  0.858587  0.868688  0.878789  0.88889  0.898991  0.909092  0.919193  0.929294  0.939395  0.949496  0.959597  0.969698  0.979799  0.9899  done.
## Finished evaluating probability density.
## Beginning volume calculation... done. 
## Quantile requested: 0.70   obtained: 0.70
## Evaluating probability density...
## Building tree... done.
## Querying tree... 9.90099e-06  0.0990198  0.19803  0.29704  0.39605  0.495059  0.594069  0.693079  0.792089  0.891099  0.990109  done.
## Finished evaluating probability density.
## Beginning volume calculation... done. 
## Quantile requested: 0.70   obtained: 0.68
## Evaluating probability density...
## Building tree... done.
## Querying tree... 2.60213e-07  0.00260239  0.00520453  0.00780666  0.0104088  0.0130109  0.0156131  0.0182152  0.0208173  0.0234195  0.0260216  0.0286237  0.0312259  0.033828  0.0364301  0.0390323  0.0416344  0.0442365  0.0468387  0.0494408  0.0520429  0.0546451  0.0572472  0.0598493  0.0624515  0.0650536  0.0676557  0.0702579  0.07286  0.0754621  0.0780643  0.0806664  0.0832685  0.0858707  0.0884728  0.0910749  0.0936771  0.0962792  0.0988813  0.101483  0.104086  0.106688  0.10929  0.111892  0.114494  0.117096  0.119698  0.122301  0.124903  0.127505  0.130107  0.132709  0.135311  0.137913  0.140515  0.143118  0.14572  0.148322  0.150924  0.153526  0.156128  0.15873  0.161333  0.163935  0.166537  0.169139  0.171741  0.174343  0.176945  0.179547  0.18215  0.184752  0.187354  0.189956  0.192558  0.19516  0.197762  0.200365  0.202967  0.205569  0.208171  0.210773  0.213375  0.215977  0.218579  0.221182  0.223784  0.226386  0.228988  0.23159  0.234192  0.236794  0.239397  0.241999  0.244601  0.247203  0.249805  0.252407  0.255009  0.257612  0.260214  0.262816  0.265418  0.26802  0.270622  0.273224  0.275826  0.278429  0.281031  0.283633  0.286235  0.288837  0.291439  0.294041  0.296644  0.299246  0.301848  0.30445  0.307052  0.309654  0.312256  0.314858  0.317461  0.320063  0.322665  0.325267  0.327869  0.330471  0.333073  0.335676  0.338278  0.34088  0.343482  0.346084  0.348686  0.351288  0.35389  0.356493  0.359095  0.361697  0.364299  0.366901  0.369503  0.372105  0.374708  0.37731  0.379912  0.382514  0.385116  0.387718  0.39032  0.392922  0.395525  0.398127  0.400729  0.403331  0.405933  0.408535  0.411137  0.41374  0.416342  0.418944  0.421546  0.424148  0.42675  0.429352  0.431954  0.434557  0.437159  0.439761  0.442363  0.444965  0.447567  0.450169  0.452772  0.455374  0.457976  0.460578  0.46318  0.465782  0.468384  0.470986  0.473589  0.476191  0.478793  0.481395  0.483997  0.486599  0.489201  0.491804  0.494406  0.497008  0.49961  0.502212  0.504814  0.507416  0.510018  0.512621  0.515223  0.517825  0.520427  0.523029  0.525631  0.528233  0.530836  0.533438  0.53604  0.538642  0.541244  0.543846  0.546448  0.54905  0.551653  0.554255  0.556857  0.559459  0.562061  0.564663  0.567265  0.569868  0.57247  0.575072  0.577674  0.580276  0.582878  0.58548  0.588082  0.590685  0.593287  0.595889  0.598491  0.601093  0.603695  0.606297  0.6089  0.611502  0.614104  0.616706  0.619308  0.62191  0.624512  0.627114  0.629717  0.632319  0.634921  0.637523  0.640125  0.642727  0.645329  0.647932  0.650534  0.653136  0.655738  0.65834  0.660942  0.663544  0.666147  0.668749  0.671351  0.673953  0.676555  0.679157  0.681759  0.684361  0.686964  0.689566  0.692168  0.69477  0.697372  0.699974  0.702576  0.705179  0.707781  0.710383  0.712985  0.715587  0.718189  0.720791  0.723393  0.725996  0.728598  0.7312  0.733802  0.736404  0.739006  0.741608  0.744211  0.746813  0.749415  0.752017  0.754619  0.757221  0.759823  0.762425  0.765028  0.76763  0.770232  0.772834  0.775436  0.778038  0.78064  0.783243  0.785845  0.788447  0.791049  0.793651  0.796253  0.798855  0.801457  0.80406  0.806662  0.809264  0.811866  0.814468  0.81707  0.819672  0.822275  0.824877  0.827479  0.830081  0.832683  0.835285  0.837887  0.840489  0.843092  0.845694  0.848296  0.850898  0.8535  0.856102  0.858704  0.861307  0.863909  0.866511  0.869113  0.871715  0.874317  0.876919  0.879521  0.882124  0.884726  0.887328  0.88993  0.892532  0.895134  0.897736  0.900339  0.902941  0.905543  0.908145  0.910747  0.913349  0.915951  0.918553  0.921156  0.923758  0.92636  0.928962  0.931564  0.934166  0.936768  0.939371  0.941973  0.944575  0.947177  0.949779  0.952381  0.954983  0.957585  0.960188  0.96279  0.965392  0.967994  0.970596  0.973198  0.9758  0.978403  0.981005  0.983607  0.986209  0.988811  0.991413  0.994015  0.996617  0.99922  done.
## Finished evaluating probability density.
## Beginning volume calculation... done. 
## Quantile requested: 0.70   obtained: 0.70
## Evaluating probability density...
## Building tree... done.
## Querying tree... 1.64204e-06  0.016422  0.0328424  0.0492627  0.0656831  0.0821034  0.0985238  0.114944  0.131365  0.147785  0.164205  0.180626  0.197046  0.213466  0.229887  0.246307  0.262727  0.279148  0.295568  0.311989  0.328409  0.344829  0.36125  0.37767  0.39409  0.410511  0.426931  0.443351  0.459772  0.476192  0.492612  0.509033  0.525453  0.541874  0.558294  0.574714  0.591135  0.607555  0.623975  0.640396  0.656816  0.673236  0.689657  0.706077  0.722498  0.738918  0.755338  0.771759  0.788179  0.804599  0.82102  0.83744  0.85386  0.870281  0.886701  0.903122  0.919542  0.935962  0.952383  0.968803  0.985223  done.
## Finished evaluating probability density.
## Beginning volume calculation... done. 
## Quantile requested: 0.70   obtained: 0.70
## Evaluating probability density...
## Building tree... done.
## Querying tree... 1.0101e-06  0.010102  0.020203  0.030304  0.0404051  0.0505061  0.0606071  0.0707081  0.0808091  0.0909101  0.101011  0.111112  0.121213  0.131314  0.141415  0.151516  0.161617  0.171718  0.181819  0.19192  0.202021  0.212122  0.222223  0.232324  0.242425  0.252526  0.262627  0.272728  0.282829  0.29293  0.303031  0.313132  0.323233  0.333334  0.343435  0.353536  0.363637  0.373738  0.383839  0.39394  0.404041  0.414142  0.424243  0.434344  0.444445  0.454546  0.464647  0.474748  0.484849  0.494951  0.505052  0.515153  0.525254  0.535355  0.545456  0.555557  0.565658  0.575759  0.58586  0.595961  0.606062  0.616163  0.626264  0.636365  0.646466  0.656567  0.666668  0.676769  0.68687  0.696971  0.707072  0.717173  0.727274  0.737375  0.747476  0.757577  0.767678  0.777779  0.78788  0.797981  0.808082  0.818183  0.828284  0.838385  0.848486  0.858587  0.868688  0.878789  0.88889  0.898991  0.909092  0.919193  0.929294  0.939395  0.949496  0.959597  0.969698  0.979799  0.9899  done.
## Finished evaluating probability density.
## Beginning volume calculation... done. 
## Quantile requested: 0.70   obtained: 0.70
## Warning in (function (data, repsperpoint = NULL, bandwidth, quantile = 0, : 
##  Dimensions x and y are highly correlated (r=-0.91)
## Consider removing some axes.
## Evaluating probability density...
## Building tree... done.
## Querying tree... 9.90099e-06  0.0990198  0.19803  0.29704  0.39605  0.495059  0.594069  0.693079  0.792089  0.891099  0.990109  done.
## Finished evaluating probability density.
## Beginning volume calculation... done. 
## Quantile requested: 0.70   obtained: 0.69
## Evaluating probability density...
## Building tree... done.
## Querying tree... 2.60213e-07  0.00260239  0.00520453  0.00780666  0.0104088  0.0130109  0.0156131  0.0182152  0.0208173  0.0234195  0.0260216  0.0286237  0.0312259  0.033828  0.0364301  0.0390323  0.0416344  0.0442365  0.0468387  0.0494408  0.0520429  0.0546451  0.0572472  0.0598493  0.0624515  0.0650536  0.0676557  0.0702579  0.07286  0.0754621  0.0780643  0.0806664  0.0832685  0.0858707  0.0884728  0.0910749  0.0936771  0.0962792  0.0988813  0.101483  0.104086  0.106688  0.10929  0.111892  0.114494  0.117096  0.119698  0.122301  0.124903  0.127505  0.130107  0.132709  0.135311  0.137913  0.140515  0.143118  0.14572  0.148322  0.150924  0.153526  0.156128  0.15873  0.161333  0.163935  0.166537  0.169139  0.171741  0.174343  0.176945  0.179547  0.18215  0.184752  0.187354  0.189956  0.192558  0.19516  0.197762  0.200365  0.202967  0.205569  0.208171  0.210773  0.213375  0.215977  0.218579  0.221182  0.223784  0.226386  0.228988  0.23159  0.234192  0.236794  0.239397  0.241999  0.244601  0.247203  0.249805  0.252407  0.255009  0.257612  0.260214  0.262816  0.265418  0.26802  0.270622  0.273224  0.275826  0.278429  0.281031  0.283633  0.286235  0.288837  0.291439  0.294041  0.296644  0.299246  0.301848  0.30445  0.307052  0.309654  0.312256  0.314858  0.317461  0.320063  0.322665  0.325267  0.327869  0.330471  0.333073  0.335676  0.338278  0.34088  0.343482  0.346084  0.348686  0.351288  0.35389  0.356493  0.359095  0.361697  0.364299  0.366901  0.369503  0.372105  0.374708  0.37731  0.379912  0.382514  0.385116  0.387718  0.39032  0.392922  0.395525  0.398127  0.400729  0.403331  0.405933  0.408535  0.411137  0.41374  0.416342  0.418944  0.421546  0.424148  0.42675  0.429352  0.431954  0.434557  0.437159  0.439761  0.442363  0.444965  0.447567  0.450169  0.452772  0.455374  0.457976  0.460578  0.46318  0.465782  0.468384  0.470986  0.473589  0.476191  0.478793  0.481395  0.483997  0.486599  0.489201  0.491804  0.494406  0.497008  0.49961  0.502212  0.504814  0.507416  0.510018  0.512621  0.515223  0.517825  0.520427  0.523029  0.525631  0.528233  0.530836  0.533438  0.53604  0.538642  0.541244  0.543846  0.546448  0.54905  0.551653  0.554255  0.556857  0.559459  0.562061  0.564663  0.567265  0.569868  0.57247  0.575072  0.577674  0.580276  0.582878  0.58548  0.588082  0.590685  0.593287  0.595889  0.598491  0.601093  0.603695  0.606297  0.6089  0.611502  0.614104  0.616706  0.619308  0.62191  0.624512  0.627114  0.629717  0.632319  0.634921  0.637523  0.640125  0.642727  0.645329  0.647932  0.650534  0.653136  0.655738  0.65834  0.660942  0.663544  0.666147  0.668749  0.671351  0.673953  0.676555  0.679157  0.681759  0.684361  0.686964  0.689566  0.692168  0.69477  0.697372  0.699974  0.702576  0.705179  0.707781  0.710383  0.712985  0.715587  0.718189  0.720791  0.723393  0.725996  0.728598  0.7312  0.733802  0.736404  0.739006  0.741608  0.744211  0.746813  0.749415  0.752017  0.754619  0.757221  0.759823  0.762425  0.765028  0.76763  0.770232  0.772834  0.775436  0.778038  0.78064  0.783243  0.785845  0.788447  0.791049  0.793651  0.796253  0.798855  0.801457  0.80406  0.806662  0.809264  0.811866  0.814468  0.81707  0.819672  0.822275  0.824877  0.827479  0.830081  0.832683  0.835285  0.837887  0.840489  0.843092  0.845694  0.848296  0.850898  0.8535  0.856102  0.858704  0.861307  0.863909  0.866511  0.869113  0.871715  0.874317  0.876919  0.879521  0.882124  0.884726  0.887328  0.88993  0.892532  0.895134  0.897736  0.900339  0.902941  0.905543  0.908145  0.910747  0.913349  0.915951  0.918553  0.921156  0.923758  0.92636  0.928962  0.931564  0.934166  0.936768  0.939371  0.941973  0.944575  0.947177  0.949779  0.952381  0.954983  0.957585  0.960188  0.96279  0.965392  0.967994  0.970596  0.973198  0.9758  0.978403  0.981005  0.983607  0.986209  0.988811  0.991413  0.994015  0.996617  0.99922  done.
## Finished evaluating probability density.
## Beginning volume calculation... done. 
## Quantile requested: 0.70   obtained: 0.70
## Warning in (function (data, repsperpoint = NULL, bandwidth, quantile = 0, : 
##  Dimensions x and y are highly correlated (r=-0.86)
## Consider removing some axes.
## Evaluating probability density...
## Building tree... done.
## Querying tree... 1.64204e-06  0.016422  0.0328424  0.0492627  0.0656831  0.0821034  0.0985238  0.114944  0.131365  0.147785  0.164205  0.180626  0.197046  0.213466  0.229887  0.246307  0.262727  0.279148  0.295568  0.311989  0.328409  0.344829  0.36125  0.37767  0.39409  0.410511  0.426931  0.443351  0.459772  0.476192  0.492612  0.509033  0.525453  0.541874  0.558294  0.574714  0.591135  0.607555  0.623975  0.640396  0.656816  0.673236  0.689657  0.706077  0.722498  0.738918  0.755338  0.771759  0.788179  0.804599  0.82102  0.83744  0.85386  0.870281  0.886701  0.903122  0.919542  0.935962  0.952383  0.968803  0.985223  done.
## Finished evaluating probability density.
## Beginning volume calculation... done. 
## Quantile requested: 0.70   obtained: 0.70
# generate prioritisation
cs_rs_amount <- solve(cs_rs_amount, MIPGap=0.1, Threads=threads)
## Optimize a model with 4 rows, 762 columns and 1336 nonzeros
## Variable types: 0 continuous, 762 integer (762 binary)
## Coefficient statistics:
##   Matrix range     [4e+02, 2e+04]
##   Objective range  [1e+00, 1e+00]
##   Bounds range     [1e+00, 1e+00]
##   RHS range        [1e+05, 3e+06]
## Found heuristic solution: objective 159
## Presolve time: 0.00s
## Presolved: 4 rows, 762 columns, 1336 nonzeros
## Variable types: 0 continuous, 762 integer (762 binary)
## Presolved: 4 rows, 762 columns, 1336 nonzeros
## 
## 
## Root relaxation: objective 1.354267e+02, 597 iterations, 0.00 seconds
## 
##     Nodes    |    Current Node    |     Objective Bounds      |     Work
##  Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time
## 
##      0     0  135.42669    0    4  159.00000  135.42669  14.8%     -    0s
## H    0     0                     136.0000000  135.42669  0.42%     -    0s
## 
## Explored 0 nodes (597 simplex iterations) in 0.01 seconds
## Thread count was 22 (of 24 available processors)
## 
## Solution count 2: 136 159 
## Pool objective bound 136
## 
## Optimal solution found (tolerance 1.00e-01)
## Best objective 1.360000000000e+02, best bound 1.360000000000e+02, gap 0.0000%
# show summary
summary(cs_rs_amount)
##   Run_Number  Status Score Cost Planning_Units Connectivity_Total
## 1          1 OPTIMAL   136  136            136           98882414
##   Connectivity_In Connectivity_Edge Connectivity_Out
## 1         9786021          81270163          7826230
##   Connectivity_In_Fraction
## 1               0.09896624
# plot prioritisation
plot(cs_rs_amount, 1)

_Multi-species prioritisation generated for four bird species using amount-based targets (20\%). See Figure 12 captions for conventions._

We can also see how well the prioritisation secures the species’ distributions in the geographic and environmental attribute spaces.

# plot prioritisation in geographic attribute space
p1 <- space.plot(cs_rs_amount, 1, 2, main='Blue-winged\nkookaburra')
p2 <- space.plot(cs_rs_amount, 2, 2, main='Brown-backed\nhoneyeater')
p3 <- space.plot(cs_rs_amount, 3, 2, main='Brown falcon')
p4 <- space.plot(cs_rs_amount, 4, 2, main='Pale-headed\nrosella')
gridExtra::grid.arrange(p1, p2, p3, p4, ncol=2)

_Distribution of amount-based prioritisation in the geographic attribute space. Points denote combinations of environmental conditions. Green and grey points represent planning unit selected for and not selected for prioritisation (respectively). Blue points denote demand points, and their size indicates their weighting._

# plot prioritisation in environmental attribute space
p1 <- space.plot(cs_rs_amount, 1, 1, main='Blue-winged\nkookaburra')
p2 <- space.plot(cs_rs_amount, 2, 1, main='Brown-backed\nhoneyeater')
p3 <- space.plot(cs_rs_amount, 3, 1, main='Brown falcon')
p4 <- space.plot(cs_rs_amount, 4, 1, main='Pale-headed\nrosella')
gridExtra::grid.arrange(p1, p2, p3, p4, ncol=2)

_Distribution of amount-based prioritisation in the environmental attribute space. See Figure 28 caption for conventions._

Next, let’s generate a prioritisation using amount- and space-based targets. This prioritisation will secure 70% of the species distribution in geographic and environmental space.

# make amount- and space-based prioritisation
cs_rs_space <- update(cs_rs_amount, space.target=0.7, Threads=threads)
## Optimize a model with 134012 rows, 134362 columns and 535736 nonzeros
## Variable types: 0 continuous, 134362 integer (134362 binary)
## Coefficient statistics:
##   Matrix range     [1e-03, 2e+04]
##   Objective range  [1e+00, 1e+00]
##   Bounds range     [1e+00, 1e+00]
##   RHS range        [1e+00, 3e+06]
## Presolve removed 2742 rows and 1698 columns (presolve time = 5s) ...
## Presolve removed 3205 rows and 1698 columns (presolve time = 10s) ...
## Presolve removed 3439 rows and 1698 columns (presolve time = 15s) ...
## Presolve removed 3594 rows and 1698 columns (presolve time = 20s) ...
## Presolve removed 4816 rows and 1698 columns (presolve time = 25s) ...
## Presolve removed 5783 rows and 1698 columns (presolve time = 30s) ...
## Presolve removed 6001 rows and 1698 columns (presolve time = 35s) ...
## Presolve removed 6042 rows and 1698 columns (presolve time = 40s) ...
## Presolve removed 6091 rows and 1698 columns (presolve time = 45s) ...
## Presolve removed 6826 rows and 1698 columns (presolve time = 50s) ...
## Presolve removed 7833 rows and 1698 columns (presolve time = 55s) ...
## Presolve removed 8053 rows and 1698 columns (presolve time = 60s) ...
## Presolve removed 8085 rows and 1698 columns (presolve time = 73s) ...
## Presolve removed 8085 rows and 1698 columns
## Presolve time: 73.07s
## Presolved: 125927 rows, 132664 columns, 583968 nonzeros
## Variable types: 0 continuous, 132664 integer (132664 binary)
## Found heuristic solution: objective 247.0000000
## Presolve removed 337 rows and 0 columns
## Presolved: 125590 rows, 132664 columns, 582841 nonzeros
## 
## Presolve removed 125590 rows and 132664 columns
## 
## Root simplex log...
## 
## Iteration    Objective       Primal Inf.    Dual Inf.      Time
##        0    7.6200000e+02   0.000000e+00   7.620000e+02     77s
##    16189    1.3624264e+02   0.000000e+00   1.088315e+03     80s
##    30247    1.3562235e+02   0.000000e+00   4.064113e+02     85s
##    38513    1.3552449e+02   0.000000e+00   0.000000e+00     88s
##    38513    1.3552449e+02   0.000000e+00   0.000000e+00     88s
## 
## Root relaxation: objective 1.355245e+02, 38513 iterations, 14.11 seconds
## 
##     Nodes    |    Current Node    |     Objective Bounds      |     Work
##  Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time
## 
##      0     0  135.52449    0  190  247.00000  135.52449  45.1%     -   88s
## H    0     0                     136.0000000  135.52449  0.35%     -   89s
## 
## Explored 0 nodes (52705 simplex iterations) in 89.06 seconds
## Thread count was 22 (of 24 available processors)
## 
## Solution count 2: 136 247 
## Pool objective bound 136
## 
## Optimal solution found (tolerance 1.00e-01)
## Best objective 1.360000000000e+02, best bound 1.360000000000e+02, gap 0.0000%
# show summary
summary(cs_rs_space)
##   Run_Number  Status Score Cost Planning_Units Connectivity_Total
## 1          1 OPTIMAL   136  136            136           98882414
##   Connectivity_In Connectivity_Edge Connectivity_Out
## 1         9638090          81018598          8225726
##   Connectivity_In_Fraction
## 1               0.09747021
# plot prioritisation
plot(cs_rs_space,1)

plot of chunk unnamed-chunk-58

# plot prioritisation in geographic attribute space
p1 <- space.plot(cs_rs_space, 1, 2, main='Blue-winged\nkookaburra')
p2 <- space.plot(cs_rs_space, 2, 2, main='Brown-backed\nhoneyeater')
p3 <- space.plot(cs_rs_space, 3, 2, main='Brown falcon')
p4 <- space.plot(cs_rs_space, 4, 2, main='Pale-headed\nrosella')
gridExtra::grid.arrange(p1, p2, p3, p4, ncol=2)
Distribution of the amount- and space-based prioritisation in the geographic attribute space. See Figure 28 caption for conventions.

Distribution of the amount- and space-based prioritisation in the geographic attribute space. See Figure 28 caption for conventions.

# plot prioritisation in environmental attribute space
p1 <- space.plot(cs_rs_space, 1, 1, main='Blue-winged\nkookaburra')
p2 <- space.plot(cs_rs_space, 2, 1, main='Brown-backed\nhoneyeater')
p3 <- space.plot(cs_rs_space, 3, 1, main='Brown falcon')
p4 <- space.plot(cs_rs_space, 4, 1, main='Pale-headed\nrosella')
gridExtra::grid.arrange(p1, p2, p3, p4, ncol=2)

_Distribution of the amount- and space-based prioritisation in the environmental attribute space. See Figure 28 caption for conventions._

Let’s compare these prioritisations with Queensland’s existing protected areas system. To do this, we can create update the cs_rs_space with manually specified solutions to create a RapSolved object to represent the Queensland’s reserve network.

# generate vector with Australia's selections
aus_selections <- which(cs_pus$status>0)

# create new object with Australia's network
cs_rs_aus <- update(cs_rs_amount, b=aus_selections)

Now, let’s plot the performance metrics for these prioritisations.

# define standard error function
se=function(x){sd(x,na.rm=TRUE)/sqrt(sum(!is.na(x)))}

# create a table to store the values for the 3 prioritisations
cs_results <- data.frame(
    name=factor(rep(rep(c('Amount-based\nprioritisation', 
        'Amount & space-based\nprioritisation', 'Queensland reserve\nnetwork'),
        each=4),3), levels=c(c('Amount-based\nprioritisation', 
        'Amount & space-based\nprioritisation', 'Queensland reserve\nnetwork'))),
    variable=rep(c('Amount', 'Geographic space', 'Environmental space'), each=12),
    species=colnames(amount.held(cs_rs_amount)),
    value=c(
        amount.held(cs_rs_amount)[1,], amount.held(cs_rs_space)[1,],
            amount.held(cs_rs_aus)[1,],
        space.held(cs_rs_amount, space=2)[1,], space.held(cs_rs_space, space=2)[1,], 
            space.held(cs_rs_aus, space=2)[1,],
        space.held(cs_rs_amount, space=1)[1,], space.held(cs_rs_space, space=1)[1,],
            space.held(cs_rs_aus, space=1)[1,]
    )
) %>% group_by(name,variable) %>%
    summarise(mean=mean(value),se=se(value))

# plot the performance metrics
ggplot(aes(x=variable, y=mean, fill=name), data=cs_results) +
    geom_bar(position=position_dodge(0.9), stat='identity') +
    geom_errorbar(
        aes(ymin=mean-se, ymax=mean+se), position=position_dodge(0.9),
        width=0.2) +
    xlab('Property of species') +
    ylab('Proportion held in\nselected planning units (%)') +
    scale_fill_discrete(name='') +
    theme_classic() +
    theme(legend.position='bottom',legend.direction='horizontal',
        axis.line.x=element_line(),axis.line.y=element_line())

_Prioritisations were generated using amount-based targets (20\%), and with additional space-based targets (85\%). These are compared to the Queensland reserve network. Data represent means and standard errors for the four species in each prioritisation._ We can see that a greater number of planning units is needed to satisfy the space-based targets. The prioritisation generated using just amount-based targets has 136 planning units, and the prioritisations using amount-based and space-based targets has 136 planning units. These results suggest only a few additional planning units can result in significant improvements in the effectivenss of a prioritisation.