Learn R Programming

prioritizr (version 5.0.3)

add_linear_penalties: Add linear penalties

Description

Add penalties to a conservation planning problem() to penalize solutions that select planning units with higher values from a specific data source (e.g. anthropogenic impact). These penalties assume a linear trade-off between the penalty values and the primary objective of the conservation planning problem() (e.g. solution cost for minimum set problems; add_min_set_objective().

Usage

# S4 method for ConservationProblem,ANY,character
add_linear_penalties(x, penalty, data)

# S4 method for ConservationProblem,ANY,numeric add_linear_penalties(x, penalty, data)

# S4 method for ConservationProblem,ANY,matrix add_linear_penalties(x, penalty, data)

# S4 method for ConservationProblem,ANY,Matrix add_linear_penalties(x, penalty, data)

# S4 method for ConservationProblem,ANY,Raster add_linear_penalties(x, penalty, data)

# S4 method for ConservationProblem,ANY,dgCMatrix add_linear_penalties(x, penalty, data)

Arguments

x

problem() (i.e. '>ConservationProblem) object.

penalty

numeric penalty value that is used to scale the importance not selecting planning units with high data values. Higher penalty values can be used to obtain solutions that are strongly averse to selecting places with high data values, and smaller penalty values can be used to obtain solutions that only avoid places with especially high data values. Note that negative penalty values can be used to obtain solutions that prefer places with high data values. Additionally, when adding these penalties to problems with multiple zones, the argument to penalty must have a value for each zone.

data

character, numeric, '>Raster, matrix, or Matrix object containing the data used to penalize solutions. Planning units that are associated with higher data values are penalized more strongly in the solution. See the Details section for more information.

Details

This function penalizes solutions that have higher values according to a specific metric. The argument to data can be specified in several different ways:

character

field (column) name(s) that contain the data for penalizing planning units. This type of argument is only compatible if the planning units in the argument to x are a '>Spatial, sf::sf(), or data.frame object. The fields (columns) must have numeric values, and must not contain any missing (NA) values. For problems involving multiple zones, the argument to data must contain a field name for each zone.

numeric

vector containing the data for penalizing each planning unit. These values must not contain any missing (NA) values. Note that this type of argument is only available for planning units that contain a single zone.

'>Raster

containing the data for penalizing planning units. This type of argument is only compatible if the planning units in the argument to x are '>Spatial, sf::sf(), or or '>Raster (i.e. they are in a spatially referenced format). If the planning unit data are a '>Spatial or sf::sf() object, then the penalty data are calculated by overlaying the planning units with the argument to data and calculating the sum of the values. If the planning unit data are in the '>Raster then the penalty data are calculated by extracting the cell values (note that the planning unit data and the argument to codedata must have exactly the same dimensionality, extent, and missingness). For problems involving multiple zones, the argument to data must contain a layer for each zone.

matrix, Matrix

containing numeric values that specify data for penalizing each planning unit. Each row corresponds to a planning unit, each column corresponds to a zone, and each cell indicates the data for penalizing a planning unit when it is allocated to a given zone.

The linear penalties are calculated using the following equations. Let \(I\) denote the set of planning units (indexed by \(i\)), \(Z\) the set of management zones (indexed by \(z\)), and \(X_{iz}\) the decision variable for allocating planning unit \(i\) to zone \(z\) (e.g. with binary values one indicating if planning unit is allocated or not). Also, let \(P_z\) represent the penalty scaling value for zones \(z \in Z\) (argument to penalty), and \(D_{iz}\) the penalty data for allocating planning unit \(i \in I\) to zones \(z \in Z\) (argument to data if supplied as a matrix object).

$$ \sum_{i}^{I} \sum_{z}^{Z} P_z \times D_{iz} \times X_{iz} $$

Note that when the problem objective is to maximize some measure of benefit and not minimize some measure of cost, the term \(P_z\) is replaced with \(-P_z\).

Examples

Run this code
# NOT RUN {
# set seed for reproducibility
set.seed(600)

# load data
data(sim_pu_polygons, sim_pu_zones_stack, sim_features, sim_features_zones)

# add a column to contain the penalty data for each planning unit
# e.g. these values could indicate the level of habitat
sim_pu_polygons$penalty_data <- runif(nrow(sim_pu_polygons))

# plot the penalty data to visualise its spatial distribution
spplot(sim_pu_polygons, zcol = "penalty_data", main = "penalty data",
       axes = FALSE, box = FALSE)

# create minimal problem with minimum set objective,
# this does not use the penalty data
p1 <- problem(sim_pu_polygons, sim_features, cost_column = "cost") %>%
      add_min_set_objective() %>%
      add_relative_targets(0.1) %>%
      add_binary_decisions()

# print problem
print(p1)

# create an updated version of the previous problem,
# with the penalties added to it
p2 <- p1 %>% add_linear_penalties(100, data = "penalty_data")

# print problem
print(p2)

# }
# NOT RUN {
# solve the two problems
s1 <- solve(p1)
s2 <- solve(p2)

# plot the solutions and compare them,
# since we supplied a very high penalty value (i.e. 100), relative
# to the range of values in the penalty data and the objective function,
# the solution in s2 is very sensitive to values in the penalty data
spplot(s1, zcol = "solution_1", main = "solution without penalties",
       axes = FALSE, box = FALSE)
spplot(s2, zcol = "solution_1", main = "solution with penalties",
       axes = FALSE, box = FALSE)

# for real conservation planning exercises,
# it would be worth exploring a range of penalty values (e.g. ranging
# from 1 to 100 increments of 5) to explore the trade-offs
# }
# NOT RUN {
# now, let's examine a conservation planning exercise involving multiple
# management zones

# create targets for each feature within each zone,
# these targets indicate that each zone needs to represent 10% of the
# spatial distribution of each feature
targ <- matrix(0.1, ncol = number_of_zones(sim_features_zones),
               nrow = number_of_features(sim_features_zones))

# create penalty data for allocating each planning unit to each zone,
# these data will be generated by simulating values
penalty_stack <- simulate_cost(sim_pu_zones_stack[[1]],
                               n = number_of_zones(sim_features_zones))

# plot the penalty data, each layer corresponds to a different zone
plot(penalty_stack, main = "penalty data", axes = FALSE, box = FALSE)

# create a multi-zone problem with the minimum set objective
# and penalties for allocating planning units to each zone,
# with a penalty scaling factor of 1 for each zone
p3 <- problem(sim_pu_zones_stack, sim_features_zones) %>%
      add_min_set_objective() %>%
      add_relative_targets(targ) %>%
      add_linear_penalties(c(1, 1, 1), penalty_stack) %>%
      add_binary_decisions()

# print problem
print(p3)

# }
# NOT RUN {
# solve problem
s3 <- solve(p3)

# plot solution
plot(category_layer(s3), main = "multi-zone solution",
     axes = FALSE, box = FALSE)
# }

Run the code above in your browser using DataLab