diff --git a/.github/workflows/MacOS.yaml b/.github/workflows/MacOS.yaml index eeb6db9..f44ef01 100644 --- a/.github/workflows/MacOS.yaml +++ b/.github/workflows/MacOS.yaml @@ -46,6 +46,7 @@ jobs: any::rcmdcheck any::remotes any::lpsymphony + any::slam needs: check - uses: r-lib/actions/check-r-package@v2 diff --git a/.github/workflows/Ubuntu.yaml b/.github/workflows/Ubuntu.yaml index 03878a2..562a505 100644 --- a/.github/workflows/Ubuntu.yaml +++ b/.github/workflows/Ubuntu.yaml @@ -53,6 +53,7 @@ jobs: any::rcmdcheck any::remotes any::lpsymphony + any::slam needs: check - uses: r-lib/actions/check-r-package@v2 diff --git a/.github/workflows/Windows.yaml b/.github/workflows/Windows.yaml index e46efd1..76154cf 100644 --- a/.github/workflows/Windows.yaml +++ b/.github/workflows/Windows.yaml @@ -50,6 +50,7 @@ jobs: any::rcmdcheck any::remotes any::lpsymphony + any::slam needs: check - uses: r-lib/actions/check-r-package@v2 diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index 870ee9f..b8b6e9f 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -42,6 +42,7 @@ jobs: any::rcmdcheck any::remotes any::lpsymphony + any::slam needs: coverage - name: Test coverage diff --git a/NAMESPACE b/NAMESPACE index 71160bc..21b3247 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -68,11 +68,9 @@ importFrom(dplyr,summarise) importFrom(dplyr,summarize) importFrom(dplyr,tibble) importFrom(dplyr,ungroup) -importFrom(forcats,fct_relevel) importFrom(ggnewscale,new_scale_colour) importFrom(ggnewscale,new_scale_fill) importFrom(ggplot2,aes) -importFrom(ggplot2,after_stat) importFrom(ggplot2,annotate) importFrom(ggplot2,coord_polar) importFrom(ggplot2,coord_sf) @@ -80,7 +78,6 @@ importFrom(ggplot2,element_blank) importFrom(ggplot2,element_line) importFrom(ggplot2,element_rect) importFrom(ggplot2,element_text) -importFrom(ggplot2,expansion) importFrom(ggplot2,geom_abline) importFrom(ggplot2,geom_bar) importFrom(ggplot2,geom_segment) diff --git a/R/data.R b/R/data.R index 83b1a7d..a5c7650 100644 --- a/R/data.R +++ b/R/data.R @@ -1,6 +1,6 @@ #' Planning Units #' -#' An sf dataframe of planning units for spatial prioritisation +#' An sf dataframe of Planning Units for spatial prioritization #' #' @format `dat_PUs` #' A data frame with XXXX rows and XXX columns: @@ -14,9 +14,9 @@ # ------------------------------------------------------------------------- -#' Boundary of planning units +#' Boundary of Planning Units #' -#' An sf dataframe of planning units for spatial prioritisation +#' An sf dataframe of Planning Units for spatial prioritization #' #' @format `dat_bndry` #' A data frame with XXXX rows and XXX columns: @@ -32,7 +32,7 @@ #' Regionalisation #' -#' An sf dataframe of planning units for spatial prioritisation +#' An sf dataframe of Planning Units for spatial prioritization #' #' @format `dat_region` #' A data frame with XXXX rows and XXX columns: @@ -47,7 +47,7 @@ #' Binary Species Data #' -#' An sf dataframe of planning units for spatial prioritisation +#' An sf dataframe of Planning Units for spatial prioritization #' #' @format `dat_species_bin` #' A data frame with XXXX rows and XXX columns: @@ -63,7 +63,7 @@ #' Binary Species Data 2 #' -#' An sf dataframe of planning units for spatial prioritisation +#' An sf dataframe of Planning Units for spatial prioritization #' #' @format `dat_species_bin2` #' A data frame with XXXX rows and XXX columns: @@ -79,7 +79,7 @@ #' Probability Species Data #' -#' An sf dataframe of planning units for spatial prioritisation +#' An sf dataframe of Planning Units for spatial prioritization #' #' @format `dat_species_prob` #' A data frame with XXXX rows and XXX columns: @@ -93,9 +93,9 @@ # ------------------------------------------------------------------------- -#' MPA Data +#' Marine Protected Areas (MPAs) Data #' -#' An sf dataframe of planning units for spatial prioritisation +#' An sf dataframe of Planning Units for spatial prioritization #' #' @format `dat_mpas` #' A data frame with XXXX rows and XXX columns: @@ -117,7 +117,7 @@ #' @format `dat_category` #' A data frame with XXXX rows and XXX columns: #' \describe{ -#' \item{feature}{all features available for spatial prioritisation} +#' \item{feature}{all features available for spatial prioritization} #' \item{category}{the categories of all features} #' ... #' } @@ -135,7 +135,7 @@ #' @format `dat_category2` #' A data frame with XXXX rows and XXX columns: #' \describe{ -#' \item{feature}{all features available for spatial prioritisation} +#' \item{feature}{all features available for spatial prioritization} #' \item{category}{the categories of all features} #' ... #' } @@ -148,7 +148,7 @@ #' Climate metric data #' -#' An sf dataframe of planning units for spatial prioritisation +#' An sf dataframe of Planning Units for spatial prioritization #' #' @format `dat_clim` #' A data frame with 780 rows and 3 columns: @@ -179,14 +179,14 @@ # ------------------------------------------------------------------------- -#' Current MPAs of the Coral Sea +#' Current Marine Protected Areas (MPAs) of the Coral Sea #' -#' sf file containing the current marine protected areas of the coral sea +#' sf file containing the current Marine Protected Areas (MPAs) of the coral sea #' #' @format `MPAsCoralSea` #' A data frame with 397 rows and 17 columns: #' \describe{ -#' \item{wdpa}{binary vector denoting presence or absence of a current marine protected area} +#' \item{wdpa}{binary vector denoting presence or absence of a current MPA} #' ... #' } #' @source https://www.protectedplanet.net/en/thematic-areas/wdpa?tab=WDPA diff --git a/R/splnr_get_distCoast.R b/R/splnr_get_distCoast.R index 37ac46a..92f6273 100644 --- a/R/splnr_get_distCoast.R +++ b/R/splnr_get_distCoast.R @@ -2,7 +2,7 @@ #' #' @description #' This function calculates the shortest distance from the centroid of each -#' planning unit in an `sf` object to the nearest coastline. It can use either +#' Planning Unit in an `sf` object to the nearest coastline. It can use either #' a default coastline from the `rnaturalearth` package or a custom-provided #' coastline `sf` object. #' @@ -13,7 +13,7 @@ #' a suitable projected CRS for accurate distance calculations. #' #' @param dat_sf `[sf]` \cr An `sf` object containing polygon or point features -#' representing the planning units. Must have a valid CRS. +#' representing the Planning Units. Must have a valid CRS. #' @param custom_coast `[sf]` \cr An optional `sf` object representing a #' custom coastline. If `NULL` (the default), the coastline is downloaded #' from `rnaturalearth`. @@ -99,12 +99,12 @@ splnr_get_distCoast <- function(dat_sf, custom_coast = NULL, res = "medium") { sf::st_transform(crs = sf::st_crs(dat_sf)) } - # Calculate centroids of the planning units - # Using centroids is a standard approach to represent the location of each planning unit - message("Calculating centroids for planning units.") + # Calculate centroids of the Planning Units + # Using centroids is a standard approach to represent the location of each Planning Unit + message("Calculating centroids for Planning Units.") grid_centroid <- sf::st_centroid(sf::st_geometry(dat_sf)) - # Calculate the distance matrix between each planning unit centroid and the coastline + # Calculate the distance matrix between each Planning Unit centroid and the coastline message("Calculating distances to coastline.") dist_mat <- sf::st_distance(grid_centroid, coast) %>% # Explicitly set the distance units to kilometers @@ -112,7 +112,7 @@ splnr_get_distCoast <- function(dat_sf, custom_coast = NULL, res = "medium") { # Drop the units class to get a numeric matrix for easier computation units::drop_units() - # Find the minimum distance for each planning unit (each row in the matrix) + # Find the minimum distance for each Planning Unit (each row in the matrix) # This identifies the shortest distance from each centroid to any part of the coastline message("Finding minimum distances and adding to dataframe.") dat_sf$coastDistance_km <- do.call(pmin, as.data.frame(dist_mat)) diff --git a/R/splnr_gg_add.R b/R/splnr_gg_add.R index da74780..c8fd4ad 100644 --- a/R/splnr_gg_add.R +++ b/R/splnr_gg_add.R @@ -1,16 +1,18 @@ -#' @title Add-ons for Plotting `spatialplanr` Maps +#' @title Add-ons for Plotting `spatialplanr` Solution Maps #' #' @description -#' This function allows users to customize existing `ggplot2` maps, particularly -#' those produced by other `spatialplanr` spatial plotting functions. It provides -#' options to add various spatial layers and apply consistent theming in a +#' This function allows users to customize existing `ggplot2` solution maps produced +#' by `spatialplanr` spatial plotting functions (e.g., `splnr_plot_solution()`). It +#' provides options to add various spatial layers and apply consistent theming in a #' simple and reproducible manner. #' #' @details -#' The `splnr_gg_add` function enhances `ggplot2` objects by layering additional -#' spatial data such as planning unit outlines, study area boundaries, general -#' overlays, geographical contours, and 'locked-in' areas (e.g., existing protected -#' areas in a conservation prioritization). It offers fine-grained control over +#' The `splnr_gg_add()` function enhances `ggplot2` objects by layering additional +#' spatial data such as Planning Unit outlines, study area boundaries, general +#' overlays, geographical contours, locked-in areas (e.g., existing Marine Protected +#' Areas (MPAs) that must be included in a conservation prioritization), and +#' locked-out areas (e.g., areas that must be excluded from selection such as +#' shipping lanes or oil and gas leases). It offers fine-grained control over #' colors, opacities, and legend appearance for each added layer. #' #' When using `contours`, the input `sf` object is expected to have a column @@ -23,10 +25,10 @@ #' or `NA` (logical `FALSE`) to apply no default theme, allowing the user to manage #' all theme elements manually. #' -#' @param PUs An `sf` object representing planning units. If provided, their +#' @param PUs An `sf` object representing Planning Units. If provided, their #' outlines will be drawn. Defaults to `NULL`. #' @param colorPUs A character string specifying the color for the outlines of the -#' planning units. Defaults to `"grey80"`. +#' Planning Units. Defaults to `"grey80"`. #' @param Bndry An `sf` object representing the main planning region boundaries. #' If provided, its outline will be drawn. Defaults to `NULL`. #' @param colorBndry A character string specifying the color for the outline of the @@ -41,15 +43,15 @@ #' @param colorOverlay3 A character string specifying the color for `overlay3`. #' Defaults to `"grey40"`. #' @param cropOverlay An `sf` object. Its bounding box will be used to set the -#' `xlim` and `ylim` of the `ggplot2::coord_sf` layer, effectively cropping the view. +#' `xlim` and `ylim` of the `ggplot2::coord_sf()` layer, effectively cropping the view. #' Defaults to `NULL`. #' @param contours An `sf` object containing contour lines (e.g., bathymetry or #' seamount outlines). It is expected to have a `Category` column for differentiating #' lines. Up to 6 categories are supported. Defaults to `NULL`. #' @param colorConts A character string specifying the color for the contour lines. #' Defaults to `"black"`. -#' @param lockIn An `sf` object representing 'locked-in' areas (e.g., existing -#' Marine Protected Areas) that are fixed in a conservation prioritization. +#' @param lockIn An `sf` object representing locked-in areas (e.g., existing +#' Marine Protected Areas (MPAs)) that are fixed in a conservation prioritization. #' Defaults to `NULL`. #' @param typeLockIn A character string specifying how `lockIn` areas should be #' plotted. Can be `"Full"` (fills the areas with `colorLockIn`) or `"Contours"` @@ -58,13 +60,30 @@ #' data frame that contains binary (0/1 or TRUE/FALSE) information indicating #' locked-in status. Required if `lockIn` is not `NULL`. #' @param alphaLockIn A numeric value (0 to 1) for the opacity of the `lockIn` -#' areas when `typeLockIn` is `"Full"`. Defaults to `0.5`. +#' areas when `typeLockIn` is `"Full"`. Defaults to `1`. #' @param colorLockIn A character string specifying the color for the `lockIn` areas. #' Defaults to `"black"`. #' @param legendLockIn A character string for the title of the `lockIn` legend. #' Can be an empty string `""` to suppress the title. Defaults to `""`. #' @param labelLockIn A character string for the legend label of the `lockIn` areas #' (e.g., "MPAs"). Defaults to `"MPAs"`. +#' @param lockOut An `sf` object representing locked-out areas (e.g., shipping lanes, +#' oil and gas leases, or other excluded zones) that must not be selected in a +#' conservation prioritization. Defaults to `NULL`. +#' @param typeLockOut A character string specifying how `lockOut` areas should be +#' plotted. Can be `"Full"` (fills the areas with `colorLockOut`) or `"Contours"` +#' (draws only the outlines of the areas). Defaults to `"Full"`. +#' @param nameLockOut A character string specifying the column name in the `lockOut` +#' data frame that contains binary (0/1 or TRUE/FALSE) information indicating +#' locked-out status. Required if `lockOut` is not `NULL`. +#' @param alphaLockOut A numeric value (0 to 1) for the opacity of the `lockOut` +#' areas when `typeLockOut` is `"Full"`. Defaults to `1`. +#' @param colorLockOut A character string specifying the color for the `lockOut` areas. +#' Defaults to `"black"`. +#' @param legendLockOut A character string for the title of the `lockOut` legend. +#' Can be an empty string `""` to suppress the title. Defaults to `""`. +#' @param labelLockOut A character string for the legend label of the `lockOut` areas +#' (e.g., "Shipping Lanes"). Defaults to `""`. #' @param ggtheme The `ggplot2` theme to apply. Can be: #' \itemize{ #' \item `NA` or `FALSE`: No theme is applied, using `ggplot2` defaults. @@ -91,7 +110,7 @@ #' @examples #' \dontrun{ #' # Assuming 'dat_species_bin' and 'dat_PUs' are existing sf objects -#' # in your package, suitable for prioritisation problems and plotting. +#' # in your package, suitable for prioritization problems and plotting. #' #' # Create a dummy prioritizr problem and solve it for demonstration. #' dat_problem <- prioritizr::problem( @@ -107,13 +126,13 @@ #' dat_soln <- dat_problem %>% #' prioritizr::solve.ConservationProblem() #' -#' # Basic plot of the solution with default planning unit outlines and theme. +#' # Basic plot of the solution with default Planning Unit outlines and theme. #' plot_basic <- splnr_plot_solution(dat_soln) + #' splnr_gg_add(PUs = dat_PUs, ggtheme = "Default") #' print(plot_basic) #' #' # Example with boundary, a custom overlay, and locked-in areas shown as contours. -#' # For this example, let's create dummy `bndry_sf` and `locked_in_sf` based on `dat_PUs` +#' # For this example, let's create dummy `bndry_sf` and `locked_in_sf` based on `dat_PUs`. #' # In a real scenario, these would be loaded from your package or data. #' bndry_sf <- sf::st_union(dat_PUs) %>% sf::st_as_sf() #' locked_in_sf <- dat_PUs[1:100, ] %>% dplyr::mutate(is_mpa = 1) @@ -125,7 +144,6 @@ #' colorBndry = "darkblue", #' overlay = bndry_sf, # Using boundary as an example overlay #' colorOverlay = "lightblue", -#' alphaOverlay = 0.3, #' lockIn = locked_in_sf, #' typeLockIn = "Contours", #' nameLockIn = "is_mpa", @@ -164,37 +182,58 @@ splnr_gg_add <- function(PUs = NULL, colorPUs = "grey80", # TODO Remove all uneeded arguments, especially the lockIn - # TODO Update the asserts for new arguments - # # Assertions to validate input parameters are of the correct 'sf' class if not NULL. - # if(!is.null(PUs)){assertthat::assert_that(inherits(PUs, "sf"), msg = "'PUs' must be an 'sf' object or NULL.")} - # if(!is.null(Bndry)){assertthat::assert_that(inherits(Bndry, "sf"), msg = "'Bndry' must be an 'sf' object or NULL.")} - # if(!is.null(overlay)){assertthat::assert_that(inherits(overlay, "sf"), msg = "'overlay' must be an 'sf' object or NULL.")} - # if(!is.null(overlay2)){assertthat::assert_that(inherits(overlay2, "sf"), msg = "'overlay2' must be an 'sf' object or NULL.")} - # if(!is.null(overlay3)){assertthat::assert_that(inherits(overlay3, "sf"), msg = "'overlay3' must be an 'sf' object or NULL.")} - # if(!is.null(contours)){assertthat::assert_that(inherits(contours, "sf"), msg = "'contours' must be an 'sf' object or NULL.")} - # if(!is.null(lockIn)){ - # assertthat::assert_that(inherits(lockIn, "sf"), msg = "'lockIn' must be an 'sf' object or NULL.") - # assertthat::assert_that(is.character(nameLockIn) && all(nameLockIn %in% names(lockIn)), - # msg = "If 'lockIn' is provided, 'nameLockIn' must be a character string specifying an existing column in 'lockIn'.") - # assertthat::assert_that(typeLockIn %in% c("Full", "Contours"), - # msg = "'typeLockIn' must be either 'Full' or 'Contours'.") - # assertthat::assert_that(is.numeric(alphaLockIn) && alphaLockIn >= 0 && alphaLockIn <= 1, - # msg = "'alphaLockIn' must be a numeric value between 0 and 1.") - # } - # if(!is.null(cropOverlay)){assertthat::assert_that(inherits(cropOverlay, "sf"), msg = "'cropOverlay' must be an 'sf' object or NULL.")} - # assertthat::assert_that(is.character(colorPUs), msg = "'colorPUs' must be a character string for a color.") - # assertthat::assert_that(is.character(colorBndry), msg = "'colorBndry' must be a character string for a color.") - # assertthat::assert_that(is.character(colorOverlay), msg = "'colorOverlay' must be a character string for a color.") - # assertthat::assert_that(is.character(colorOverlay2), msg = "'colorOverlay2' must be a character string for a color.") - # assertthat::assert_that(is.character(colorOverlay3), msg = "'colorOverlay3' must be a character string for a color.") - # assertthat::assert_that(is.character(colorConts), msg = "'colorConts' must be a character string for a color.") - # assertthat::assert_that(is.character(colorLockIn), msg = "'colorLockIn' must be a character string for a color.") - # assertthat::assert_that(is.character(legendLockIn), msg = "'legendLockIn' must be a character string.") - # assertthat::assert_that(is.character(labelLockIn), msg = "'labelLockIn' must be a character string.") - # assertthat::assert_that( - # inherits(ggtheme, "character") || inherits(ggtheme, "theme") || inherits(ggtheme, "logical"), - # msg = "'ggtheme' must be 'Default', a ggplot2 theme, or NA/FALSE." - # ) + # Assertions to validate input parameters are of the correct 'sf' class if not NULL. + if(!is.null(PUs)){assertthat::assert_that(inherits(PUs, "sf"), msg = "'PUs' must be an 'sf' object or NULL.")} + if(!is.null(Bndry)){assertthat::assert_that(inherits(Bndry, "sf"), msg = "'Bndry' must be an 'sf' object or NULL.")} + if(!is.null(overlay)){assertthat::assert_that(inherits(overlay, "sf"), msg = "'overlay' must be an 'sf' object or NULL.")} + if(!is.null(overlay2)){assertthat::assert_that(inherits(overlay2, "sf"), msg = "'overlay2' must be an 'sf' object or NULL.")} + if(!is.null(overlay3)){assertthat::assert_that(inherits(overlay3, "sf"), msg = "'overlay3' must be an 'sf' object or NULL.")} + if(!is.null(contours)){assertthat::assert_that(inherits(contours, "sf"), msg = "'contours' must be an 'sf' object or NULL.")} + if(!is.null(cropOverlay)){assertthat::assert_that(inherits(cropOverlay, "sf"), msg = "'cropOverlay' must be an 'sf' object or NULL.")} + + # Validate lockIn parameters + if(!is.null(lockIn)){ + assertthat::assert_that(inherits(lockIn, "sf"), msg = "'lockIn' must be an 'sf' object or NULL.") + assertthat::assert_that(is.character(nameLockIn) && !is.null(nameLockIn) && all(nameLockIn %in% names(lockIn)), + msg = "If 'lockIn' is provided, 'nameLockIn' must be a character string specifying an existing column in 'lockIn'.") + assertthat::assert_that(typeLockIn %in% c("Full", "Contours"), + msg = "'typeLockIn' must be either 'Full' or 'Contours'.") + assertthat::assert_that(is.numeric(alphaLockIn) && alphaLockIn >= 0 && alphaLockIn <= 1, + msg = "'alphaLockIn' must be a numeric value between 0 and 1.") + } + + # Validate lockOut parameters + if(!is.null(lockOut)){ + assertthat::assert_that(inherits(lockOut, "sf"), msg = "'lockOut' must be an 'sf' object or NULL.") + assertthat::assert_that(is.character(nameLockOut) && !is.null(nameLockOut) && all(nameLockOut %in% names(lockOut)), + msg = "If 'lockOut' is provided, 'nameLockOut' must be a character string specifying an existing column in 'lockOut'.") + assertthat::assert_that(typeLockOut %in% c("Full", "Contours"), + msg = "'typeLockOut' must be either 'Full' or 'Contours'.") + assertthat::assert_that(is.numeric(alphaLockOut) && alphaLockOut >= 0 && alphaLockOut <= 1, + msg = "'alphaLockOut' must be a numeric value between 0 and 1.") + } + + # Validate color parameters + assertthat::assert_that(is.character(colorPUs), msg = "'colorPUs' must be a character string for a color.") + assertthat::assert_that(is.character(colorBndry), msg = "'colorBndry' must be a character string for a color.") + assertthat::assert_that(is.character(colorOverlay), msg = "'colorOverlay' must be a character string for a color.") + assertthat::assert_that(is.character(colorOverlay2), msg = "'colorOverlay2' must be a character string for a color.") + assertthat::assert_that(is.character(colorOverlay3), msg = "'colorOverlay3' must be a character string for a color.") + assertthat::assert_that(is.character(colorConts), msg = "'colorConts' must be a character string for a color.") + assertthat::assert_that(is.character(colorLockIn), msg = "'colorLockIn' must be a character string for a color.") + assertthat::assert_that(is.character(colorLockOut), msg = "'colorLockOut' must be a character string for a color.") + + # Validate legend and label parameters + assertthat::assert_that(is.character(legendLockIn), msg = "'legendLockIn' must be a character string.") + assertthat::assert_that(is.character(labelLockIn), msg = "'labelLockIn' must be a character string.") + assertthat::assert_that(is.character(legendLockOut), msg = "'legendLockOut' must be a character string.") + assertthat::assert_that(is.character(labelLockOut), msg = "'labelLockOut' must be a character string.") + + # Validate ggtheme parameter + assertthat::assert_that( + inherits(ggtheme, "character") || inherits(ggtheme, "theme") || inherits(ggtheme, "list") || inherits(ggtheme, "logical"), + msg = "'ggtheme' must be 'Default', a ggplot2 theme, a list of theme elements, or NA/FALSE." + ) # Initialize an empty list to store ggplot2 layers. ggList <- list() diff --git a/R/splnr_plotting.R b/R/splnr_plotting.R index 76f0fe4..cb013d2 100644 --- a/R/splnr_plotting.R +++ b/R/splnr_plotting.R @@ -4,14 +4,14 @@ #' This function provides a versatile way to plot spatial data (`sf` objects) #' within the `spatialplanr` package. It can visualize various data types, #' including binary presence/absence, logical values, continuous data, or simply -#' the planning unit outlines. +#' the Planning Unit outlines. #' #' @details -#' The `splnr_plot` function automatically detects the type of data specified by +#' The `splnr_plot()` function automatically detects the type of data specified by #' `colNames` (binary, logical, or continuous) and adjusts the plotting #' aesthetics accordingly. If multiple `colNames` are provided, it calculates -#' the sum of features for each planning unit and plots this sum. If `colNames` -#' is `NULL`, it will simply plot the outlines of the planning units. +#' the sum of features for each Planning Unit and plots this sum. If `colNames` +#' is `NULL`, it will simply plot the outlines of the Planning Units. #' #' This function is designed to be a flexible replacement for several plotting #' functions, such as `splnr_plot_cost()`, `splnr_plot_binFeature()`, @@ -24,7 +24,7 @@ #' @param df The input dataframe containing the data to be plotted. This must be #' an `sf` object and include a geometry column. #' @param colNames A character vector of column names from `df` to be used for -#' coloring the plot. If `NULL` (default), only the planning unit outlines are plotted. +#' coloring the plot. If `NULL` (default), only the Planning Unit outlines are plotted. #' If a single column is specified, it checks for binary, logical, or continuous data. #' If multiple columns are specified, it sums the values across these columns to create #' a "FeatureSum" for plotting. @@ -258,9 +258,9 @@ splnr_plot <- function(df, ggplot2::guides(fill = ggplot2::guide_colourbar(order = 1), colour = "none") - } else if (is.null(colNames)){ # If no column to plot by (only planning unit outlines). + } else if (is.null(colNames)){ # If no column to plot by (only Planning Unit outlines). - # Add geom_sf to display planning unit outlines without fill. + # Add geom_sf to display Planning Unit outlines without fill. gg <- gg + ggplot2::geom_sf(data = df, colour = "grey80", fill = NA, size = 0.1) } @@ -284,7 +284,7 @@ splnr_plot <- function(df, #' by combining it with the `spatialplanr` function `splnr_gg_add()`. #' #' For multi-zone problems (`zones = TRUE`), the function sums the selected -#' zones for each planning unit and plots the resulting combined selection. +#' zones for each Planning Unit and plots the resulting combined selection. #' The `colorVals` and `legendLabels` should be provided to match the number of #' selection levels (e.g., "Not selected", "Zone 1", "Zone 2", etc.). #' @@ -448,7 +448,7 @@ splnr_plot_solution <- function(soln, colorVals = c("#c6dbef", "#3182bd"), ) } - # Sum up the zone selections for each planning unit to get a single 'solution' column. + # Sum up the zone selections for each Planning Unit to get a single 'solution' column. soln <- solnNewNames %>% dplyr::rowwise() %>% dplyr::mutate( @@ -504,24 +504,24 @@ splnr_plot_solution <- function(soln, colorVals = c("#c6dbef", "#3182bd"), #' @title Plot Cost Overlay on Solution #' #' @description -#' The `splnr_plot_costOverlay()` function visualizes the cost of each planning -#' unit overlaid on the solution of a `prioritizr` conservation problem. This +#' The `splnr_plot_costOverlay()` function visualizes the cost of each Planning +#' Unit overlaid on the solution of a `prioritizr` conservation problem. This #' allows for a customizable `ggplot2` visualization, highlighting the costs -#' within selected planning units. +#' within selected Planning Units. #' #' @details #' This function requires a `prioritizr` solution as an `sf` object, which #' must contain a `solution_1` column indicating selected (1) or unselected (0) -#' planning units. It also requires a cost column, either present within the +#' Planning Units. It also requires a cost column, either present within the #' `soln` object or provided separately via the `Cost` parameter. #' -#' The function filters the solution to show only the selected planning units +#' The function filters the solution to show only the selected Planning Units #' and then overlays these with a gradient representing the cost. This output #' is a `ggplot` object that can be further customized using `splnr_gg_add()`. #' #' @param soln The `prioritizr` solution object, expected as an `sf` object, #' containing at least a `solution_1` column. -#' @param cost An `sf` object containing the cost data for planning units. +#' @param cost An `sf` object containing the cost data for Planning Units. #' If the `prioritizr` solution `soln` already contains the cost column #' specified by `costName`, this parameter can be `NA` (default). Otherwise, #' provide an `sf` object with the cost data. @@ -622,7 +622,7 @@ splnr_plot_costOverlay <- function(soln, cost = NA, costName = "Cost", stop(paste0("The provided 'Cost' object does not contain the specified cost column '", costName, "'.")) } - # Filter the solution to only include selected planning units. + # Filter the solution to only include selected Planning Units. soln <- soln %>% dplyr::select("solution_1") %>% dplyr::filter(.data$solution_1 == 1) @@ -658,7 +658,7 @@ splnr_plot_costOverlay <- function(soln, cost = NA, costName = "Cost", #' @description #' The `splnr_plot_comparison()` function spatially visualizes the differences #' between two `prioritizr` conservation solutions. This helps in understanding -#' which planning units are common, added, or removed between two scenarios. +#' which Planning Units are common, added, or removed between two scenarios. #' #' @details #' Conservation planning often involves comparing outputs from different @@ -667,7 +667,7 @@ splnr_plot_costOverlay <- function(soln, cost = NA, costName = "Cost", #' `prioritizr` solution and containing a `solution_1` column (binary, #' indicating selected vs. not selected). #' -#' The function categorizes planning units into "Same" (selected in both), +#' The function categorizes Planning Units into "Same" (selected in both), #' "Added (+)" (selected in `soln2` but not `soln1`), and "Removed (-)" #' (selected in `soln1` but not `soln2`). It then plots these categories with #' distinct colors for clear visualization. The output is a `ggplot` object @@ -770,7 +770,7 @@ splnr_plot_comparison <- function(soln1, soln2, legendTitle = "Scenario 2 compar ), Compare = factor(.data$Compare, levels = c("Added (+)", "Same", "Removed (-)")) # Set factor levels for consistent plotting order. ) %>% - # Filter out any planning units that are NA in the 'Compare' column (e.g., neither were selected in either scenario). + # Filter out any Planning Units that are NA in the 'Compare' column (e.g., neither were selected in either scenario). dplyr::filter(!is.na(.data$Compare)) # Initialize the ggplot object. @@ -794,16 +794,16 @@ splnr_plot_comparison <- function(soln1, soln2, legendTitle = "Scenario 2 compar #' #' @description #' The `splnr_plot_selectionFreq()` function visualizes the selection frequency -#' of planning units across an array of `prioritizr` solutions. This is useful +#' of Planning Units across an array of `prioritizr` solutions. This is useful #' for understanding which areas are consistently selected as important for #' conservation. #' #' @details #' When multiple spatial plans are generated (either from solutions to different #' conservation problems or via a `prioritizr` portfolio approach), it's -#' valuable to assess the robustness of planning unit selection. This function +#' valuable to assess the robustness of Planning Unit selection. This function #' takes an `sf` object as input, which must contain a `selFreq` column -#' representing the selection frequency of each planning unit. This `selFreq` +#' representing the selection frequency of each Planning Unit. This `selFreq` #' column can be generated using the `spatialplanr` function `splnr_get_selFreq()`. #' #' The function uses `ggplot2` to create a spatial plot of these frequencies, @@ -811,7 +811,7 @@ splnr_plot_comparison <- function(soln1, soln2, legendTitle = "Scenario 2 compar #' The output is a `ggplot` object that can be further enhanced by combining it #' with the `spatialplanr` function `splnr_gg_add()`. #' -#' @param selFreq An `sf` object containing the selection frequency data for planning units. +#' @param selFreq An `sf` object containing the selection frequency data for Planning Units. #' This object must include a `selFreq` column (e.g., generated by `splnr_get_selFreq()`). #' @param plotTitle A character string for the title of the plot. Defaults to `""`. #' @param paletteName A character string or numeric value specifying the name of the @@ -821,7 +821,7 @@ splnr_plot_comparison <- function(soln1, soln2, legendTitle = "Scenario 2 compar #' @param legendTitle A character string for the title of the legend. #' Defaults to `"Selection \nFrequency"`. #' -#' @return A `ggplot` object representing the plot of planning unit selection frequency. +#' @return A `ggplot` object representing the plot of Planning Unit selection frequency. #' @export #' #' @importFrom assertthat assert_that @@ -928,11 +928,11 @@ splnr_plot_selectionFreq <- function(selFreq, #' #' @description #' The `splnr_plot_importanceScore()` function visualizes the importance scores -#' (irreplaceability) of planning units from a `prioritizr` conservation problem +#' (irreplaceability) of Planning Units from a `prioritizr` conservation problem #' using `ggplot2`. It supports different methods for calculating importance scores. #' #' @details -#' Importance scores quantify the irreplaceability of a planning unit in a +#' Importance scores quantify the irreplaceability of a Planning Unit in a #' conservation solution. This function leverages the `prioritizr` package to #' calculate and plot three different types of importance scores: #' \itemize{ diff --git a/R/splnr_plotting_climate.R b/R/splnr_plotting_climate.R index eed0d9e..596638a 100644 --- a/R/splnr_plotting_climate.R +++ b/R/splnr_plotting_climate.R @@ -412,16 +412,17 @@ splnr_plot_climKernelDensity_Fancy <- function(solution_list, #' stakeholder engagement. #' #' Both underlying functions require a `prioritizr` solution containing a -#' `metric` column with climate metric information and a `solution_1` column +#' climate metric column with climate metric information and a prioritizr solution column #' indicating selected planning units. #' #' @param soln For `type = "Normal"`: A `list` of `prioritizr` solution objects #' (e.g., `list(s1, s2)`). Each solution must contain a `metric` column and #' a `solution_1` column. #' For `type = "Basic"`: A single `prioritizr` solution `sf` object. -#' @param names A character vector of names corresponding to each solution in +#' @param solution_names A character vector of names corresponding to each solution in #' `soln` when `type = "Normal"`. Not used for `type = "Basic"`. #' Defaults to `NA`. +#' @param climate_names A character string of the name of the climate #' @param type A character string specifying the plotting style. Must be either #' `"Normal"` or `"Basic"`. Defaults to `"Normal"`. #' @param colorMap A character string indicating the `viridis` color map to use @@ -491,7 +492,7 @@ splnr_plot_climKernelDensity_Fancy <- function(solution_list, #' # Example 2: Normal (Fancy) kernel density plot for a single solution #' plot_normal_kde_single <- splnr_plot_climKernelDensity( #' soln = list(dat_solnClim), -#' names = c("Solution 1"), +#' solution_names = c("Solution 1"), #' type = "Normal" #' ) #' print(plot_normal_kde_single) @@ -503,7 +504,8 @@ splnr_plot_climKernelDensity_Fancy <- function(solution_list, #' #' plot_normal_kde_multi <- splnr_plot_climKernelDensity( #' soln = list(dat_solnClim, dat_solnClim_2), -#' names = c("Solution A", "Solution B"), +#' solution_names = c("Solution A", "Solution B"), +#' climate_names = "metric", #' type = "Normal", #' colorMap = "plasma", #' legendTitle = "Climate Value", diff --git a/R/splnr_targets.R b/R/splnr_targets.R index 76851fa..2d398ed 100644 --- a/R/splnr_targets.R +++ b/R/splnr_targets.R @@ -13,10 +13,10 @@ #' range-restricted features. #' #' The calculation proceeds as follows: -#' 1. The area of a single planning unit is determined. +#' 1. The area of a single Planning Unit is determined. #' 2. The total area of the study region is estimated by multiplying the number -#' of planning units by the individual planning unit area. -#' 3. For each feature (species), its total area across all planning units is +#' of Planning Units by the individual Planning Unit area. +#' 3. For each feature (species), its total area across all Planning Units is #' calculated. #' 4. The target for each feature is then scaled between `target_min` and #' `target_max` such that features with smaller areas receive targets closer @@ -25,11 +25,11 @@ #' #' The input `df` is expected to be an `sf` object where columns (excluding #' geometry) represent different features (e.g., species presence/absence) and -#' rows represent planning units. +#' rows represent Planning Units. #' #' @param df An `sf` dataframe containing the features (e.g., species distribution #' data) for which to calculate inverse area targets. Each column (excluding -#' geometry) should represent a feature, and each row a planning unit. +#' geometry) should represent a feature, and each row a Planning Unit. #' @param target_min A numeric value between 0 and 1 (inclusive) specifying the #' minimum target percentage. This will be the target for the most widespread feature. #' @param target_max A numeric value between 0 and 1 (inclusive) specifying the @@ -85,7 +85,7 @@ splnr_targets_byInverseArea <- function(df, target_min, target_max) { msg = "'df' must contain a 'geometry' column." ) - # Calculate the area of a single planning unit in km². + # Calculate the area of a single Planning Unit in km². PU_area_km2 <- as.numeric(sf::st_area(df[1, ]) / 1e+06) # Calculate the total approximate area of the study region. @@ -354,7 +354,7 @@ splnr_targets_byIUCN <- function(dat, IUCN_target, IUCN_col = "IUCN_Category") { # Use coalesce to update 'target' only where new IUCN_target_value is not NA. dplyr::mutate(target = dplyr::coalesce(.data$IUCN_target_value, .data$target)) %>% # Remove the temporary IUCN_target_value column. - dplyr::select(-.data$IUCN_target_value) + dplyr::select(-"IUCN_target_value") } else if (is.numeric(IUCN_target) && length(IUCN_target) == 1) { # If IUCN_target is a single numeric, apply to specific threatened IUCN categories. diff --git a/R/utils-climate.R b/R/utils-climate.R index 4710608..e5de6a9 100644 --- a/R/utils-climate.R +++ b/R/utils-climate.R @@ -35,9 +35,9 @@ #' #' @param features An `sf` object representing conservation features. Each column #' (excluding geometry) should typically be a binary representation of a feature's -#' presence (1) or absence (0) in each planning unit. +#' presence (1) or absence (0) in each Planning Unit. #' @param metric An `sf` object containing climate metric information. It must -#' have a column named 'metric' with the climate metric values for each planning unit. +#' have a column named 'metric' with the climate metric values for each Planning Unit. #' @param percentile A numeric value (0-100) representing the cutoff threshold for #' determining climate-smart areas. For example, `percentile = 5` means the #' most climate-smart 5% of areas (based on `direction`) are considered. @@ -144,7 +144,7 @@ splnr_climate_priorityArea_preprocess <- function(features, # Handle cases where filteredDF might be empty (feature not present in any unit or only in NAs) if (nrow(filteredDF) == 0) { - warning(paste0("Feature '", spp[i], "' is not present in any planning unit with valid metric data. Skipping climate-smart area calculation for this feature.")) + warning(paste0("Feature '", spp[i], "' is not present in any Planning Unit with valid metric data. Skipping climate-smart area calculation for this feature.")) # Create an empty sf object with expected columns for binding later temp_df <- df %>% dplyr::mutate(V1 = 0, V2 = 0) %>% # Add V1 and V2 columns with 0 values @@ -459,9 +459,9 @@ splnr_climate_priorityArea_assignTargets <- function(targets, #' @param features An `sf` object representing conservation features (e.g., species #' distribution data). Each column (excluding geometry) should typically be a #' binary representation of a feature's presence (1) or absence (0) in each -#' planning unit. +#' Planning Unit. #' @param metric An `sf` object containing climate metric information. It must -#' have a column named 'metric' with the climate metric values per planning unit. +#' have a column named 'metric' with the climate metric values per Planning Unit. #' @param targets A `data.frame` with two columns: `feature` (character, listing #' the original feature names) and `target` (numeric, the initial conservation #' target for each feature as a proportion, e.g., 0.3). @@ -480,7 +480,7 @@ splnr_climate_priorityArea_assignTargets <- function(targets, #' @return A `list` with two components: #' \itemize{ #' \item `Features`: An `sf` object containing the binary information per -#' planning unit for each feature, now split into `_CS` (climate-smart) +#' Planning Unit for each feature, now split into `_CS` (climate-smart) #' and `_NCS` (non-climate-smart) components. This is ready to be #' passed to `prioritizr` when creating a conservation problem. #' \item `Targets`: A `data.frame` with the adjusted targets for the @@ -621,7 +621,7 @@ splnr_climate_priorityAreaApproach <- function(features, #' #' @param features An `sf` object representing conservation features. #' @param metric An `sf` object containing climate metric information. It must -#' have a column named 'metric' with the climate metric values per planning unit. +#' have a column named 'metric' with the climate metric values per Planning Unit. #' @param percentile A numeric value (0-100) representing the cutoff threshold for #' determining whether an area is a climate priority area or not. This is applied #' globally to the `metric` data. @@ -632,8 +632,8 @@ splnr_climate_priorityAreaApproach <- function(features, #' } #' #' @return An `sf` dataframe identical to the input `features`, but with an -#' additional binary column named `climate_layer` indicating which planning -#' units are considered climate-smart. +#' additional binary column named `climate_layer` indicating which Planning +#' Units are considered climate-smart. #' @keywords internal #' @noRd #' @importFrom assertthat assert_that @@ -888,7 +888,7 @@ splnr_climate_feature_assignTargets <- function(climateSmartDF, #' @param features An `sf` object representing conservation features (e.g., species #' distribution data). #' @param metric An `sf` object containing climate metric information. It must -#' have a column named 'metric' with the climate metric values per planning unit. +#' have a column named 'metric' with the climate metric values per Planning Unit. #' @param targets A `data.frame` with two columns: `feature` (character, listing #' the original feature names) and `target` (numeric, the initial conservation #' target for each feature as a proportion, e.g., 0.3). @@ -906,7 +906,7 @@ splnr_climate_feature_assignTargets <- function(climateSmartDF, #' @return A `list` with two components: #' \itemize{ #' \item `Features`: An `sf` object containing the binary information per -#' planning unit for each original feature, plus the new `climate_layer` +#' Planning Unit for each original feature, plus the new `climate_layer` #' feature. This is ready to be passed to `prioritizr`. #' \item `Targets`: A `data.frame` with the adjusted targets for all features, #' including the `climate_layer`. This is also ready for `prioritizr`. @@ -1052,9 +1052,9 @@ splnr_climate_featureApproach <- function(features, #' #' @param features An `sf` object representing conservation features. Each column #' (excluding geometry) should typically be a binary representation of a feature's -#' presence (1) or absence (0) in each planning unit. +#' presence (1) or absence (0) in each Planning Unit. #' @param metric An `sf` object containing climate metric information. It must -#' have a column named 'metric' with the climate metric values per planning unit. +#' have a column named 'metric' with the climate metric values per Planning Unit. #' @param percentile A numeric value (0-100) representing the cutoff threshold for #' determining whether an area is a climate priority area or not. This is applied #' *per feature* to its distribution. @@ -1066,7 +1066,7 @@ splnr_climate_featureApproach <- function(features, #' #' @return An `sf` dataframe where each column represents an original feature, #' but its values are now filtered (`_filtered` suffix implicitly removed in `rename_all`) -#' to 1 only in planning units that are part of its climate-smart percentile. +#' to 1 only in Planning Units that are part of its climate-smart percentile. #' All other values are 0. The dataframe retains the original geometry. #' @keywords internal #' @noRd @@ -1164,7 +1164,7 @@ splnr_climate_percentile_preprocess <- function(features, # Handle cases where filteredDF might be empty (feature not present in any unit or only in NAs) if (nrow(filteredDF) == 0) { - warning(paste0("Feature '", spp[i], "' is not present in any planning unit with valid metric data. Skipping percentile calculation for this feature.")) + warning(paste0("Feature '", spp[i], "' is not present in any Planning Unit with valid metric data. Skipping percentile calculation for this feature.")) # Create an empty df with expected column for binding later temp_df <- df %>% sf::st_drop_geometry() %>% # Drop geometry for consistency with other iterations @@ -1409,7 +1409,7 @@ splnr_climate_percentile_assignTargets <- function(features, #' @param features An `sf` object representing conservation features (e.g., species #' distribution data). #' @param metric An `sf` object containing climate metric information. It must -#' have a column named 'metric' with the climate metric values per planning unit. +#' have a column named 'metric' with the climate metric values per Planning Unit. #' @param targets A `data.frame` with two columns: `feature` (character, listing #' the original feature names) and `target` (numeric, the initial conservation #' target for each feature as a proportion, e.g., 0.3). @@ -1425,7 +1425,7 @@ splnr_climate_percentile_assignTargets <- function(features, #' @return A `list` with two components: #' \itemize{ #' \item `Features`: An `sf` object containing the binary information per -#' planning unit for each feature, now filtered to include only its +#' Planning Unit for each feature, now filtered to include only its #' climate-smart occurrences. This is ready to be passed to `prioritizr`. #' \item `Targets`: A `data.frame` with the adjusted targets for the #' filtered features. This is also ready for `prioritizr`. diff --git a/R/utils.R b/R/utils.R index 8d1cbeb..0cc1fd7 100644 --- a/R/utils.R +++ b/R/utils.R @@ -97,8 +97,8 @@ splnr_create_polygon <- function(x, cCRS = "EPSG:4326") { #' #' @details #' This function is useful for imputing missing data in spatial contexts. -#' It identifies all planning units with `NA` values in the `vari` column. -#' For each of these, it finds the geographically closest planning unit that +#' It identifies all Planning Units with `NA` values in the `vari` column. +#' For each of these, it finds the geographically closest Planning Unit that #' *does not* have an `NA` value in `vari`, and then copies that non-missing #' value. This approach leverages the spatial autocorrelation often present #' in environmental and species data. @@ -677,7 +677,7 @@ splnr_get_kappaCorrData <- function(sol, name_sol) { # Transform the long-format results into a wide-format correlation matrix. matrix_final <- s_matrix_all %>% tibble::as_tibble(.name_repair = "unique") %>% - dplyr::select(-.data$kappa_pvalue) %>% # Remove p-value column as it's not needed for the correlation matrix plot. + dplyr::select(-"kappa_pvalue") %>% # Remove p-value column as it's not needed for the correlation matrix plot. tidyr::pivot_wider(names_from = "plan2", values_from = "kappa_corrvalue") %>% # Pivot to make 'plan2' names as new columns. as.matrix() # Convert to matrix format. @@ -700,7 +700,7 @@ splnr_get_kappaCorrData <- function(sol, name_sol) { #' @title Prepare Data to Plot Selection Frequency of Planning Units #' #' @description -#' `splnr_get_selFreq()` calculates how many times each planning unit is +#' `splnr_get_selFreq()` calculates how many times each Planning Unit is #' selected across an array of `prioritizr` solutions. This "selection #' frequency" can be derived from either a list of individual solutions or #' a `prioritizr` portfolio object. @@ -711,7 +711,7 @@ splnr_get_kappaCorrData <- function(sol, name_sol) { #' planning scenarios or alternative optimal solutions. #' #' The function supports two types of input: -#' \itemize{ +#' \itemize{ #' \item `"portfolio"`: If `solnMany` is a single `sf` object representing a #' portfolio of solutions (e.g., generated by `prioritizr::add_cuts_portfolio()`). #' In this case, the function assumes columns starting with "solution_" @@ -721,7 +721,7 @@ splnr_get_kappaCorrData <- function(sol, name_sol) { #' "solution_1" column). #' } #' For both types, the function sums the binary `solution` values (0 or 1) -#' across all solutions for each planning unit. The result is converted to a +#' across all solutions for each Planning Unit. The result is converted to a #' factor to represent discrete frequency levels. #' #' The output `sf` object can then be passed to `splnr_plot_selectionFreq()` @@ -737,7 +737,7 @@ splnr_get_kappaCorrData <- function(sol, name_sol) { #' #' @return An `sf` object (`selFreq`) containing a column named `selFreq`. #' This column is a factor representing the selection frequency (sum of -#' selected occurrences across all solutions) for each planning unit. +#' selected occurrences across all solutions) for each Planning Unit. #' @export #' #' @importFrom assertthat assert_that @@ -817,7 +817,7 @@ splnr_get_selFreq <- function(solnMany, type = "portfolio") { # Calculate selection frequency for a portfolio (sf object with multiple solution columns). selFreq <- solnMany %>% # Convert to tibble for dplyr operations on columns, ensuring unique names. - dplyr::mutate(selFreq = as.factor(rowSums(dplyr::select(tibble::as_tibble(.), + dplyr::mutate(selFreq = as.factor(rowSums(dplyr::select(tibble::as_tibble(solnMany), dplyr::starts_with("solution_")), na.rm = TRUE))) %>% # Convert back to sf, explicitly retaining the original geometry. sf::st_as_sf(geometry = sf::st_geometry(solnMany)) %>% @@ -863,13 +863,11 @@ splnr_get_selFreq <- function(solnMany, type = "portfolio") { colnames(soln) <- name_sol # Calculate selection frequency by summing binary solution columns. + # Sum across all columns starting with "soln" (which are our individual solutions). selFreq <- soln %>% - # Sum across all columns starting with "soln" (which are our individual solutions). - dplyr::mutate(selFreq = as.factor(rowSums(dplyr::select(., dplyr::starts_with("soln")), na.rm = TRUE))) %>% - # Convert back to sf, using the geometry from the first solution in the list. - sf::st_as_sf(geometry = sf::st_geometry(solnMany[[1]])) %>% - # Select only the calculated selection frequency column. - dplyr::select("selFreq") + dplyr::mutate(selFreq = as.factor(rowSums(dplyr::select(soln, dplyr::starts_with("soln")), na.rm = TRUE))) %>% + sf::st_as_sf(geometry = sf::st_geometry(solnMany[[1]])) %>% # Convert back to sf + dplyr::select("selFreq") # Select only the calculated selection frequency column. return(selFreq) } else { diff --git a/README.Rmd b/README.Rmd index 0cef93c..8fa7be7 100644 --- a/README.Rmd +++ b/README.Rmd @@ -13,7 +13,7 @@ knitr::opts_chunk$set( ) ``` -# spatialplanr spatialplanr websitespatialplanr website [![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html#experimental) @@ -26,7 +26,7 @@ knitr::opts_chunk$set( # Introduction to spatialplanr -Welcome to _spatialplanr_, an R package designed to streamline and enhance spatial conservation prioritization efforts by explicitly integrating climate change considerations. Building upon the powerful _prioritizr_ package, _spatialplanr_ provides a suite of tools for conservation planners to develop more robust and climate-resilient protected area networks. +Welcome to _spatialplanr_, an R package designed to streamline and enhance spatial conservation prioritization efforts by explicitly integrating climate change considerations. Building upon the powerful _prioritizr_ package, _spatialplanr_ provides a suite of tools for conservation planners to develop robust protected area networks. ## Installation @@ -37,335 +37,335 @@ Be aware that this package is in the very early stages of development. Functions devtools::install_github("https://github.com/SpatialPlanning/spatialplanr") ``` -# Purpose and Goals + -The escalating impacts of climate change necessitate a paradigm shift in how we approach conservation. Traditional conservation planning often focuses on static biodiversity patterns, which may not adequately account for the dynamic nature of species distributions and ecosystem processes under a changing climate. _spatialplanr_ aims to address this gap by: + -**Facilitating Climate-Smart Planning**: Providing functions that incorporate climate data directly into the planning process, allowing for the identification of areas critical for both biodiversity and resilience to future climate conditions. -Offering Diverse Methodological Approaches: Implementing multiple established climate-smart conservation planning frameworks (e.g., Climate Priority Areas, Climate Features, Climate Percentiles) to offer flexibility based on specific planning goals and data availability. + + -**Streamlining Workflow**: Offering end-to-end functionality, from data preprocessing and integration to advanced visualization of results, simplifying complex analytical tasks for users. + -**Enhancing Decision-Making**: Producing outputs that directly feed into spatial prioritization software like prioritizr, enabling the generation of optimal conservation solutions that balance biodiversity representation with climate resilience. -By using spatialplanr, practitioners can move beyond reactive conservation and proactively design protected area systems better equipped to safeguard biodiversity in a rapidly changing world. + + -# Core Climate-Smart Planning Approaches + -_spatialplanr_ implements several key approaches for integrating climate change into spatial prioritization, largely drawing inspiration from frameworks like that presented in Buenafe et al. (2023) "A metric‐based framework for climate‐smart conservation planning" (DOI: 10.1002/eap.2852). + -These approaches are designed to transform biodiversity features and conservation targets based on climate metrics, allowing for a more nuanced understanding of how climate change may impact conservation priorities. The main approaches included in _spatialplanr_ are: - * **Climate Priority Area (CPA) Approach**: Identifies climate-smart areas within the distribution of each conservation feature, creating new components for climate-smart and non-climate-smart areas. - * **Climate Feature Approach**: Treats climate-smart areas as a distinct conservation feature, allowing for explicit conservation targets on climate resilience. - * **Climate Percentile Approach**: Sets conservation targets based on percentile ranges of climate metrics, allowing for targeted protection of areas within specific climate resilience thresholds. + + + + -# Data Acquisition and Preprocessing Utilities -_spatialplanr_ also provides convenience functions for acquiring and preparing data, which can be crucial for climate-smart planning. - -```{r} -# Load spatialplanr -library(spatialplanr) -library(tidyverse) -``` - -1. Get IUCN Red List Data -Function: `splnr_get_IUCNRedList()` - -This function interfaces with the IUCN Red List API to retrieve conservation status information for a list of species. This data can be valuable for assigning species-specific targets (e.g., higher targets for more threatened species) or filtering species based on their conservation status. - -Note: Requires an IUCN Red List API token. - -```{r} -# # Example: Fetch IUCN data for a few marine species -# # Ensure your IUCN Red List API token is set: -# # Sys.setenv(IUCN_REDLIST_KEY = "YOUR_API_KEY") # Replace with your actual key -# -# # Example species list -# my_species <- c("Orcinus orca", "Chelonia mydas", "Thunnus thynnus") -# -# # Create a dataframe matching the expected input format -# species_df <- data.frame( -# scientific_name = my_species -# ) -# -# # Get IUCN data -# iucn_data <- splnr_get_IUCNRedList(df = species_df, species_col = "scientific_name") -# print(iucn_data) - -``` - -2. Get Global Fishing Watch (GFW) Data -Function: `splnr_get_gfw()` - -This function facilitates the retrieval of fishing activity data (e.g., apparent fishing hours) from Global Fishing Watch (GFW). GFW data can be used to inform cost layers (e.g., higher fishing effort areas might have higher opportunity costs for conservation) or as a proxy for human impact in planning units. - -Note: Requires a GFW API token. - -```{r} -# Example: Get yearly fishing hours for Australia EEZ - -gfw_data_aus <- splnr_get_gfw( - region = 'Australia', - start_date = "2021-01-01", - end_date = "2021-12-31", - temp_res = "YEARLY", - spat_res = "LOW", - region_source = "EEZ", - cCRS = "EPSG:4326", - compress = TRUE # Returns polygons aggregated by fishing hours -) -print(head(gfw_data_aus)) -``` - -## Visualization Tools -_spatialplanr_ offers a rich set of plotting functions to visualize input data, climate metrics, and most importantly, the outputs of your spatial prioritization analyses. These functions are built on ggplot2 and sf for high-quality spatial visualizations. - -1. Plot Climate Data -Function: `splnr_plot_climData()` - -Visualizes the spatial distribution of your climate metric, allowing you to quickly inspect patterns in climate velocity, temperature anomaly, or other relevant climate variables. - -```{r} -# Assuming 'dat_clim' from previous examples is available -# Plot the 'metric' column from dat_clim -splnr_plot_climData( - df = dat_clim, - colInterest = "metric", - plotTitle = "Example Climate Metric Distribution", - legendTitle = "Metric Value" -) -``` - -2. Plot Climate Kernel Density -Functions: `splnr_plot_climKernelDensity_Basic()`, `splnr_plot_climKernelDensity_Fancy()`, `splnr_plot_climKernelDensity()` - -These functions help visualize the distribution of climate metric values within selected planning units (e.g., a proposed protected area network) compared to the overall distribution. This helps assess if climate-smart areas are being adequately captured. - -`_Basic()`: Simple kernel density plot. -`_Fancy()`: More customizable kernel density plot, allowing multiple solutions and specific zones. -`_climKernelDensity()`: A wrapper function that selects between basic and fancy plots based on input type. - -```{r} -solution_df <- dat_clim %>% - dplyr::mutate( - solution_1 = sample(c(0, 1), size = dplyr::n(), replace = TRUE, prob = c(0.7, 0.3)), - metric_category = cut(metric, breaks = 3, labels = c("Low", "Medium", "High")) - ) - -# Basic kernel density plot of the metric for selected areas vs. all areas -splnr_plot_climKernelDensity( - soln = solution_df, - type = "Basic", - names = "solution_1" # Column indicating selected PUs (1=selected) -) - -# Fancy kernel density plot, perhaps with zones (if your solution has them) -# For this example, let's pretend 'solution_df' has a 'zone' column -# (this would come from a prioritizr zoned solution) -zoned_solution_df <- solution_df %>% - dplyr::mutate( - zone = sample(c("Zone A", "Zone B"), size = dplyr::n(), replace = TRUE) - ) - -# Example for Fancy (requires a list of solutions or specific structure) -# If you have multiple prioritizr solutions, you would put them in a list. -# For simplicity, we'll create a mock 'soln' list: -soln_list <- list( - Solution1 = zoned_solution_df, - Solution2 = zoned_solution_df %>% mutate(solution_1 = abs(solution_1 - 1)) # Invert selection for demo -) - -# plot_climKernelDensity handles both basic and fancy automatically -splnr_plot_climKernelDensity( - soln = soln_list, # Pass the list of solutions - names = c("metric", "metric"), - type = "Normal" # Explicitly request fancy - # zone_column = "zone" # If your solutions have zones -) -``` - -3. Plot Prioritization Solutions -Function: `splnr_plot_solution()` - -Visualizes the spatial output of a prioritizr problem, showing which planning units were selected for conservation. It supports both single-zone and multi-zone solutions. - -```{r} - -# Plot a single-zone solution -splnr_plot_solution( - soln = solution_df, - colorVals = c("grey", "darkgreen"), - legendLabels = c("Not Selected", "Selected"), - plotTitle = "Prioritization Solution (Single Zone)" -) - -# Plot a zoned solution (assuming 'zone' column exists) -# In a real scenario, this 'zone' column would be part of your prioritizr output. -# splnr_plot_solution( -# soln = zoned_solution_df, -# colorVals = c("red", "blue", "grey"), # Colors for each zone + not selected -# legendLabels = c("Zone A", "Zone B", "Not Selected"), -# plotTitle = "Prioritization Solution (Zoned)", -# zones = TRUE -# ) -``` - - -4. Plot Cost Overlay -Function: `splnr_plot_costOverlay()` - -Overlays cost data on top of a prioritization solution, helping to visualize the spatial distribution of costs relative to selected areas. - -```{r} -# Assuming 'solution_df' and adding a 'cost' column -solution_with_cost <- solution_df %>% - dplyr::mutate(cost = runif(dplyr::n(), 100, 1000)) - -splnr_plot_costOverlay( - soln = solution_with_cost, - costName = "cost", # Name of the cost column - # costName = "Acquisition Cost", - # colorVals = c("grey", "darkgreen"), - # legendLabels = c("Not Selected", "Selected"), - plotTitle = "Prioritization Solution with Cost Overlay" -) - -``` - -5. Plot Comparison -Function: `splnr_plot_comparison()` - -Compares two different prioritization solutions, highlighting areas that are uniquely selected by each solution, or selected by both. - -```{r} -# Assuming two solutions for comparison -soln1_df <- solution_df %>% - dplyr::mutate(solution_1 = sample(c(0, 1), dplyr::n(), replace = TRUE, prob = c(0.6, 0.4))) -soln2_df <- solution_df %>% - dplyr::mutate(solution_1 = sample(c(0, 1), dplyr::n(), replace = TRUE, prob = c(0.5, 0.5))) - -splnr_plot_comparison( - soln1 = soln1_df, - soln2 = soln2_df, -) - -``` - -6. Plot Selection Frequency -Function: `splnr_plot_selectionFreq()` - -Visualizes the frequency with which each planning unit is selected across multiple runs of a prioritization problem (e.g., from a sensitivity analysis or robust solution generation). - -```{r} -# # Create selection frequency data -# selection_freq_df <- solution_df %>% -# dplyr::mutate( -# selection_frequency = runif(dplyr::n(), 0, 1) # Frequency between 0 and 1 -# ) -# -# splnr_plot_selectionFreq( -# selFreq = selection_freq_df, -# plotTitle = "Selection Frequency of Planning Units", -# legendTitle = "Selection Frequency" -# ) -``` - -7. Plot Importance Score -Function: `splnr_plot_importanceScore()` - -Calculates and visualizes an "importance score" for each planning unit, which can represent its contribution to achieving targets or its irreplaceability. Useful for identifying key areas. - -```{r} -# -# splnr_plot_importanceScore( -# soln = solution_df, -# pDat = dat_species_bin, # Original biodiversity features -# method = "basic", # Or "complex" -# decimals = 2, -# plotTitle = "Planning Unit Importance Score" -# ) -``` - -8. Plot Correlation Matrix -Function: `splnr_plot_corrMat()` - -Generates a correlation matrix plot, useful for understanding relationships between different features or variables in your planning data. - -```{r} -# # Create a data matrix for correlation -# -# corr_data <- data.frame( -# Var1 = rnorm(100), -# Var2 = rnorm(100, mean = 0.5, sd = 1), -# Var3 = rnorm(100, mean = -0.2, sd = 0.5) -# ) -# # Add some correlation -# corr_data$Var2 <- corr_data$Var2 + 0.5 * corr_data$Var1 -# corr_data$Var3 <- corr_data$Var3 - 0.3 * corr_data$Var1 -# -# # Calculate correlation matrix -# corr_matrix <- cor(corr_data) -# -# splnr_plot_corrMat( -# matrix = corr_matrix, -# plotTitle = "Correlation Matrix of Variables" -# ) - -``` - -9. Generic Plotting Utility -Function: `splnr_plot()` - -A versatile plotting function that can be used to visualize any continuous or categorical data column within an sf dataframe, with options for color palettes and legend customization. Many other plotting functions in _spatialplanr_ internally use this function. - -```{r} -# Plotting the 'metric' column from 'dat_clim' using the generic plotter -splnr_plot( - df = dat_clim, - colNames = "metric", - plotTitle = "Generic Plot of Climate Metric", - legendTitle = "Metric Value", - paletteName = "viridis" # Use a viridis color palette -) - -``` - -# Example Workflow -The following example illustrates a typical workflow using _spatialplanr_ for climate-smart conservation planning. It assumes you have already prepared your planning units, biodiversity features, and cost layers. - -A typical workflow using _spatialplanr_ for climate-smart conservation planning might look like this: - -## Data Preparation: - -* Load your planning units (PUs). -* Load your biodiversity features (features). -* Load your cost layer (costs). -* Load your climate metric data (climate_data). -* (Optional) Use splnr_get_IUCNRedList() to refine species targets or splnr_get_gfw() to generate a cost layer. - -Choose Climate-Smart Approach: - -* Decide which climate-smart approach best suits your planning goals: - * `splnr_climate_priorityAreaApproach()` for prioritizing refugia for each feature. - * `splnr_climate_featureApproach()` for treating climate resilience as a standalone feature. - * `splnr_climate_percentileApproach()` for targeting specific climate metric ranges. -* Run the chosen function to obtain climate_features and climate_targets. -* Define and Solve Prioritization Problem (using _prioritizr_): - -Create a prioritizr problem using your PUs, climate_features, and climate_targets. -* Add objectives (e.g., `add_min_set_objective()`, `add_max_targets_objective()`). -* Add constraints (e.g., `add_budget_constraint()`, `add_contiguity_constraint()`, `add_locked_in_constraint()` for existing MPAs). -* Add solvers (e.g., `add_gurobi_solver()`, `add_cbc_solver()`). -* Solve the problem to get your solution. - -Visualize and Analyze Results (using _spatialplanr_ plotting functions): -* `splnr_plot_solution()` to visualize the selected planning units. -* `splnr_plot_costOverlay()` to see costs in selected areas. -* `splnr_plot_climKernelDensity()` to assess the climate characteristics of the solution. -* `splnr_plot_comparison()` to compare different scenarios or solutions. -* `splnr_plot_selectionFreq()` for robust solutions. -* `splnr_plot_importanceScore()` to identify key planning units. -* `splnr_plot_corrMat()` to understand feature relationships. - - -# Conclusion -_spatialplanr_ provides a powerful and flexible toolkit for integrating climate change considerations into spatial conservation prioritization. By offering multiple methodological approaches, streamlining data handling, and providing comprehensive visualization capabilities, it aims to empower conservation planners to create more resilient and effective protected area networks for the future. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/README.md b/README.md index b6133b1..d31f450 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# spatialplanr \“spatialplanrspatialplanr website @@ -21,8 +21,7 @@ Welcome to *spatialplanr*, an R package designed to streamline and enhance spatial conservation prioritization efforts by explicitly integrating climate change considerations. Building upon the powerful *prioritizr* package, *spatialplanr* provides a suite of tools for -conservation planners to develop more robust and climate-resilient -protected area networks. +conservation planners to develop robust protected area networks. ## Installation @@ -36,454 +35,264 @@ development version from [GitHub](https://github.com/) with: devtools::install_github("https://github.com/SpatialPlanning/spatialplanr") ``` -# Purpose and Goals - -The escalating impacts of climate change necessitate a paradigm shift in -how we approach conservation. Traditional conservation planning often -focuses on static biodiversity patterns, which may not adequately -account for the dynamic nature of species distributions and ecosystem -processes under a changing climate. *spatialplanr* aims to address this -gap by: - -**Facilitating Climate-Smart Planning**: Providing functions that -incorporate climate data directly into the planning process, allowing -for the identification of areas critical for both biodiversity and -resilience to future climate conditions. Offering Diverse Methodological -Approaches: Implementing multiple established climate-smart conservation -planning frameworks (e.g., Climate Priority Areas, Climate Features, -Climate Percentiles) to offer flexibility based on specific planning -goals and data availability. - -**Streamlining Workflow**: Offering end-to-end functionality, from data -preprocessing and integration to advanced visualization of results, -simplifying complex analytical tasks for users. - -**Enhancing Decision-Making**: Producing outputs that directly feed into -spatial prioritization software like prioritizr, enabling the generation -of optimal conservation solutions that balance biodiversity -representation with climate resilience. By using spatialplanr, -practitioners can move beyond reactive conservation and proactively -design protected area systems better equipped to safeguard biodiversity -in a rapidly changing world. - -# Core Climate-Smart Planning Approaches - -*spatialplanr* implements several key approaches for integrating climate -change into spatial prioritization, largely drawing inspiration from -frameworks like that presented in Buenafe et al. (2023) “A metric‐based -framework for climate‐smart conservation planning” (DOI: -10.1002/eap.2852). - -These approaches are designed to transform biodiversity features and -conservation targets based on climate metrics, allowing for a more -nuanced understanding of how climate change may impact conservation -priorities. The main approaches included in *spatialplanr* are: \* -**Climate Priority Area (CPA) Approach**: Identifies climate-smart areas -within the distribution of each conservation feature, creating new -components for climate-smart and non-climate-smart areas. \* **Climate -Feature Approach**: Treats climate-smart areas as a distinct -conservation feature, allowing for explicit conservation targets on -climate resilience. \* **Climate Percentile Approach**: Sets -conservation targets based on percentile ranges of climate metrics, -allowing for targeted protection of areas within specific climate -resilience thresholds. - -# Data Acquisition and Preprocessing Utilities - -*spatialplanr* also provides convenience functions for acquiring and -preparing data, which can be crucial for climate-smart planning. - -``` r -# Load spatialplanr -library(spatialplanr) -library(tidyverse) -#> ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ── -#> ✔ dplyr 1.1.4 ✔ readr 2.1.5 -#> ✔ forcats 1.0.0 ✔ stringr 1.5.1 -#> ✔ ggplot2 3.5.2 ✔ tibble 3.3.0 -#> ✔ lubridate 1.9.4 ✔ tidyr 1.3.1 -#> ✔ purrr 1.0.4 -#> ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ── -#> ✖ dplyr::filter() masks stats::filter() -#> ✖ dplyr::lag() masks stats::lag() -#> ℹ Use the conflicted package () to force all conflicts to become errors -``` - -1. Get IUCN Red List Data Function: `splnr_get_IUCNRedList()` - -This function interfaces with the IUCN Red List API to retrieve -conservation status information for a list of species. This data can be -valuable for assigning species-specific targets (e.g., higher targets -for more threatened species) or filtering species based on their -conservation status. - -Note: Requires an IUCN Red List API token. - -``` r -# # Example: Fetch IUCN data for a few marine species -# # Ensure your IUCN Red List API token is set: -# # Sys.setenv(IUCN_REDLIST_KEY = "YOUR_API_KEY") # Replace with your actual key -# -# # Example species list -# my_species <- c("Orcinus orca", "Chelonia mydas", "Thunnus thynnus") -# -# # Create a dataframe matching the expected input format -# species_df <- data.frame( -# scientific_name = my_species -# ) -# -# # Get IUCN data -# iucn_data <- splnr_get_IUCNRedList(df = species_df, species_col = "scientific_name") -# print(iucn_data) -``` - -2. Get Global Fishing Watch (GFW) Data Function: `splnr_get_gfw()` - -This function facilitates the retrieval of fishing activity data (e.g., -apparent fishing hours) from Global Fishing Watch (GFW). GFW data can be -used to inform cost layers (e.g., higher fishing effort areas might have -higher opportunity costs for conservation) or as a proxy for human -impact in planning units. - -Note: Requires a GFW API token. - -``` r -# Example: Get yearly fishing hours for Australia EEZ - -gfw_data_aus <- splnr_get_gfw( - region = 'Australia', - start_date = "2021-01-01", - end_date = "2021-12-31", - temp_res = "YEARLY", - spat_res = "LOW", - region_source = "EEZ", - cCRS = "EPSG:4326", - compress = TRUE # Returns polygons aggregated by fishing hours -) -print(head(gfw_data_aus)) -#> Simple feature collection with 6 features and 2 fields -#> Geometry type: POLYGON -#> Dimension: XY -#> Bounding box: xmin: 104.05 ymin: -8.85 xmax: 104.75 ymax: -8.65 -#> Geodetic CRS: WGS 84 -#> # A tibble: 6 × 3 -#> geometry ApparentFishingHrs GFWregionID -#> -#> 1 ((104.45 -8.75, 104.45 -8.65, 104.55 -8.65, 10… 1.04 8309 -#> 2 ((104.55 -8.75, 104.55 -8.65, 104.65 -8.65, 10… 6.45 8309 -#> 3 ((104.05 -8.85, 104.05 -8.75, 104.15 -8.75, 10… 2.89 8309 -#> 4 ((104.25 -8.85, 104.25 -8.75, 104.35 -8.75, 10… 7.34 8309 -#> 5 ((104.45 -8.85, 104.45 -8.75, 104.55 -8.75, 10… 2.02 8309 -#> 6 ((104.65 -8.85, 104.65 -8.75, 104.75 -8.75, 10… 6.32 8309 -``` - -## Visualization Tools - -*spatialplanr* offers a rich set of plotting functions to visualize -input data, climate metrics, and most importantly, the outputs of your -spatial prioritization analyses. These functions are built on ggplot2 -and sf for high-quality spatial visualizations. - -1. Plot Climate Data Function: `splnr_plot_climData()` - -Visualizes the spatial distribution of your climate metric, allowing you -to quickly inspect patterns in climate velocity, temperature anomaly, or -other relevant climate variables. - -``` r -# Assuming 'dat_clim' from previous examples is available -# Plot the 'metric' column from dat_clim -splnr_plot_climData( - df = dat_clim, - colInterest = "metric", - plotTitle = "Example Climate Metric Distribution", - legendTitle = "Metric Value" -) -``` - - - -2. Plot Climate Kernel Density Functions: - `splnr_plot_climKernelDensity_Basic()`, - `splnr_plot_climKernelDensity_Fancy()`, - `splnr_plot_climKernelDensity()` - -These functions help visualize the distribution of climate metric values -within selected planning units (e.g., a proposed protected area network) -compared to the overall distribution. This helps assess if climate-smart -areas are being adequately captured. - -`_Basic()`: Simple kernel density plot. `_Fancy()`: More customizable -kernel density plot, allowing multiple solutions and specific zones. -`_climKernelDensity()`: A wrapper function that selects between basic -and fancy plots based on input type. - -``` r -solution_df <- dat_clim %>% - dplyr::mutate( - solution_1 = sample(c(0, 1), size = dplyr::n(), replace = TRUE, prob = c(0.7, 0.3)), - metric_category = cut(metric, breaks = 3, labels = c("Low", "Medium", "High")) - ) - -# Basic kernel density plot of the metric for selected areas vs. all areas -splnr_plot_climKernelDensity( - soln = solution_df, - type = "Basic", - names = "solution_1" # Column indicating selected PUs (1=selected) -) - -#> Picking joint bandwidth of 0.0885 -#> Picking joint bandwidth of 0.077 - -``` - - - -``` r - -# Fancy kernel density plot, perhaps with zones (if your solution has them) -# For this example, let's pretend 'solution_df' has a 'zone' column -# (this would come from a prioritizr zoned solution) -zoned_solution_df <- solution_df %>% - dplyr::mutate( - zone = sample(c("Zone A", "Zone B"), size = dplyr::n(), replace = TRUE) - ) - -# Example for Fancy (requires a list of solutions or specific structure) -# If you have multiple prioritizr solutions, you would put them in a list. -# For simplicity, we'll create a mock 'soln' list: -soln_list <- list( - Solution1 = zoned_solution_df, - Solution2 = zoned_solution_df %>% mutate(solution_1 = abs(solution_1 - 1)) # Invert selection for demo -) - -# plot_climKernelDensity handles both basic and fancy automatically -splnr_plot_climKernelDensity( - soln = soln_list, # Pass the list of solutions - names = c("metric", "metric"), - type = "Normal" # Explicitly request fancy - # zone_column = "zone" # If your solutions have zones -) -#> Picking joint bandwidth of 0.071 -#> Picking joint bandwidth of 0.071 -``` - - - -3. Plot Prioritization Solutions Function: `splnr_plot_solution()` - -Visualizes the spatial output of a prioritizr problem, showing which -planning units were selected for conservation. It supports both -single-zone and multi-zone solutions. - -``` r - -# Plot a single-zone solution -splnr_plot_solution( - soln = solution_df, - colorVals = c("grey", "darkgreen"), - legendLabels = c("Not Selected", "Selected"), - plotTitle = "Prioritization Solution (Single Zone)" -) -``` - - - -``` r - -# Plot a zoned solution (assuming 'zone' column exists) -# In a real scenario, this 'zone' column would be part of your prioritizr output. -# splnr_plot_solution( -# soln = zoned_solution_df, -# colorVals = c("red", "blue", "grey"), # Colors for each zone + not selected -# legendLabels = c("Zone A", "Zone B", "Not Selected"), -# plotTitle = "Prioritization Solution (Zoned)", -# zones = TRUE -# ) -``` - -4. Plot Cost Overlay Function: `splnr_plot_costOverlay()` - -Overlays cost data on top of a prioritization solution, helping to -visualize the spatial distribution of costs relative to selected areas. - -``` r -# Assuming 'solution_df' and adding a 'cost' column -solution_with_cost <- solution_df %>% - dplyr::mutate(cost = runif(dplyr::n(), 100, 1000)) - -splnr_plot_costOverlay( - soln = solution_with_cost, - costName = "cost", # Name of the cost column - # costName = "Acquisition Cost", - # colorVals = c("grey", "darkgreen"), - # legendLabels = c("Not Selected", "Selected"), - plotTitle = "Prioritization Solution with Cost Overlay" -) -``` - - - -5. Plot Comparison Function: `splnr_plot_comparison()` - -Compares two different prioritization solutions, highlighting areas that -are uniquely selected by each solution, or selected by both. - -``` r -# Assuming two solutions for comparison -soln1_df <- solution_df %>% - dplyr::mutate(solution_1 = sample(c(0, 1), dplyr::n(), replace = TRUE, prob = c(0.6, 0.4))) -soln2_df <- solution_df %>% - dplyr::mutate(solution_1 = sample(c(0, 1), dplyr::n(), replace = TRUE, prob = c(0.5, 0.5))) - -splnr_plot_comparison( - soln1 = soln1_df, - soln2 = soln2_df, -) -``` - - - -6. Plot Selection Frequency Function: `splnr_plot_selectionFreq()` - -Visualizes the frequency with which each planning unit is selected -across multiple runs of a prioritization problem (e.g., from a -sensitivity analysis or robust solution generation). - -``` r -# # Create selection frequency data -# selection_freq_df <- solution_df %>% -# dplyr::mutate( -# selection_frequency = runif(dplyr::n(), 0, 1) # Frequency between 0 and 1 -# ) -# -# splnr_plot_selectionFreq( -# selFreq = selection_freq_df, -# plotTitle = "Selection Frequency of Planning Units", -# legendTitle = "Selection Frequency" -# ) -``` - -7. Plot Importance Score Function: `splnr_plot_importanceScore()` - -Calculates and visualizes an “importance score” for each planning unit, -which can represent its contribution to achieving targets or its -irreplaceability. Useful for identifying key areas. - -``` r -# -# splnr_plot_importanceScore( -# soln = solution_df, -# pDat = dat_species_bin, # Original biodiversity features -# method = "basic", # Or "complex" -# decimals = 2, -# plotTitle = "Planning Unit Importance Score" -# ) -``` - -8. Plot Correlation Matrix Function: `splnr_plot_corrMat()` - -Generates a correlation matrix plot, useful for understanding -relationships between different features or variables in your planning -data. - -``` r -# # Create a data matrix for correlation -# -# corr_data <- data.frame( -# Var1 = rnorm(100), -# Var2 = rnorm(100, mean = 0.5, sd = 1), -# Var3 = rnorm(100, mean = -0.2, sd = 0.5) -# ) -# # Add some correlation -# corr_data$Var2 <- corr_data$Var2 + 0.5 * corr_data$Var1 -# corr_data$Var3 <- corr_data$Var3 - 0.3 * corr_data$Var1 -# -# # Calculate correlation matrix -# corr_matrix <- cor(corr_data) -# -# splnr_plot_corrMat( -# matrix = corr_matrix, -# plotTitle = "Correlation Matrix of Variables" -# ) -``` - -9. Generic Plotting Utility Function: `splnr_plot()` - -A versatile plotting function that can be used to visualize any -continuous or categorical data column within an sf dataframe, with -options for color palettes and legend customization. Many other plotting -functions in *spatialplanr* internally use this function. - -``` r -# Plotting the 'metric' column from 'dat_clim' using the generic plotter -splnr_plot( - df = dat_clim, - colNames = "metric", - plotTitle = "Generic Plot of Climate Metric", - legendTitle = "Metric Value", - paletteName = "viridis" # Use a viridis color palette -) -#> Coordinate system already present. Adding new coordinate system, which will -#> replace the existing one. -``` - - - -# Example Workflow - -The following example illustrates a typical workflow using -*spatialplanr* for climate-smart conservation planning. It assumes you -have already prepared your planning units, biodiversity features, and -cost layers. - -A typical workflow using *spatialplanr* for climate-smart conservation -planning might look like this: - -## Data Preparation: - -- Load your planning units (PUs). -- Load your biodiversity features (features). -- Load your cost layer (costs). -- Load your climate metric data (climate_data). -- (Optional) Use splnr_get_IUCNRedList() to refine species targets or - splnr_get_gfw() to generate a cost layer. - -Choose Climate-Smart Approach: - -- Decide which climate-smart approach best suits your planning goals: - - `splnr_climate_priorityAreaApproach()` for prioritizing refugia for - each feature. - - `splnr_climate_featureApproach()` for treating climate resilience as - a standalone feature. - - `splnr_climate_percentileApproach()` for targeting specific climate - metric ranges. -- Run the chosen function to obtain climate_features and - climate_targets. -- Define and Solve Prioritization Problem (using *prioritizr*): - -Create a prioritizr problem using your PUs, climate_features, and -climate_targets. \* Add objectives (e.g., `add_min_set_objective()`, -`add_max_targets_objective()`). \* Add constraints (e.g., -`add_budget_constraint()`, `add_contiguity_constraint()`, -`add_locked_in_constraint()` for existing MPAs). \* Add solvers (e.g., -`add_gurobi_solver()`, `add_cbc_solver()`). \* Solve the problem to get -your solution. - -Visualize and Analyze Results (using *spatialplanr* plotting functions): -\* `splnr_plot_solution()` to visualize the selected planning units. \* -`splnr_plot_costOverlay()` to see costs in selected areas. \* -`splnr_plot_climKernelDensity()` to assess the climate characteristics -of the solution. \* `splnr_plot_comparison()` to compare different -scenarios or solutions. \* `splnr_plot_selectionFreq()` for robust -solutions. \* `splnr_plot_importanceScore()` to identify key planning -units. \* `splnr_plot_corrMat()` to understand feature relationships. - -# Conclusion - -*spatialplanr* provides a powerful and flexible toolkit for integrating -climate change considerations into spatial conservation prioritization. -By offering multiple methodological approaches, streamlining data -handling, and providing comprehensive visualization capabilities, it -aims to empower conservation planners to create more resilient and -effective protected area networks for the future. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/404.html b/docs/404.html index 4ca3ae9..16f564a 100644 --- a/docs/404.html +++ b/docs/404.html @@ -26,7 +26,7 @@ spatialplanr - 0.6.9 + 0.7.0 "; + if (ClipboardJS.isSupported()) { + $(document).ready(function () { + var copyButton = ""; - $("div.sourceCode").addClass("hasCopyButton"); + $("div.sourceCode").addClass("hasCopyButton"); - // Insert copy buttons: - $(copyButton).prependTo(".hasCopyButton"); + // Insert copy buttons: + $(copyButton).prependTo(".hasCopyButton"); - // Initialize tooltips: - $('.btn-copy-ex').tooltip({container: 'body'}); + // Initialize tooltips: + $('.btn-copy-ex').tooltip({ container: 'body' }); - // Initialize clipboard: - var clipboard = new ClipboardJS('[data-clipboard-copy]', { - text: function(trigger) { - return trigger.parentNode.textContent.replace(/\n#>[^\n]*/g, ""); - } - }); + // Initialize clipboard: + var clipboard = new ClipboardJS('[data-clipboard-copy]', { + text: function (trigger) { + return trigger.parentNode.textContent.replace(/\n#>[^\n]*/g, ""); + } + }); - clipboard.on('success', function(e) { - changeTooltipMessage(e.trigger, 'Copied!'); - e.clearSelection(); - }); + clipboard.on('success', function (e) { + changeTooltipMessage(e.trigger, 'Copied!'); + e.clearSelection(); + }); - clipboard.on('error', function(e) { - changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); - }); + clipboard.on('error', function (e) { + changeTooltipMessage(e.trigger, 'Press Ctrl+C or Command+C to copy'); + }); - }); - } + }); + } /* Search marking --------------------------*/ var url = new URL(window.location.href); @@ -80,80 +80,80 @@ }); } - /* Search --------------------------*/ - /* Adapted from https://github.com/rstudio/bookdown/blob/2d692ba4b61f1e466c92e78fd712b0ab08c11d31/inst/resources/bs4_book/bs4_book.js#L25 */ + /* Search --------------------------*/ + /* Adapted from https://github.com/rstudio/bookdown/blob/2d692ba4b61f1e466c92e78fd712b0ab08c11d31/inst/resources/bs4_book/bs4_book.js#L25 */ // Initialise search index on focus - var fuse; - $("#search-input").focus(async function(e) { - if (fuse) { - return; - } - - $(e.target).addClass("loading"); - var response = await fetch($("#search-input").data("search-index")); - var data = await response.json(); + var fuse; + $("#search-input").focus(async function (e) { + if (fuse) { + return; + } + + $(e.target).addClass("loading"); + var response = await fetch($("#search-input").data("search-index")); + var data = await response.json(); + + var options = { + keys: ["what", "text", "code"], + ignoreLocation: true, + threshold: 0.1, + includeMatches: true, + includeScore: true, + }; + fuse = new Fuse(data, options); + + $(e.target).removeClass("loading"); + }); + // Use algolia autocomplete var options = { - keys: ["what", "text", "code"], - ignoreLocation: true, - threshold: 0.1, - includeMatches: true, - includeScore: true, + autoselect: true, + debug: true, + hint: false, + minLength: 2, }; - fuse = new Fuse(data, options); - - $(e.target).removeClass("loading"); - }); - - // Use algolia autocomplete - var options = { - autoselect: true, - debug: true, - hint: false, - minLength: 2, - }; - var q; -async function searchFuse(query, callback) { - await fuse; - - var items; - if (!fuse) { - items = []; - } else { - q = query; - var results = fuse.search(query, { limit: 20 }); - items = results - .filter((x) => x.score <= 0.75) - .map((x) => x.item); - if (items.length === 0) { - items = [{dir:"Sorry 😿",previous_headings:"",title:"No results found.",what:"No results found.",path:window.location.href}]; + var q; + async function searchFuse(query, callback) { + await fuse; + + var items; + if (!fuse) { + items = []; + } else { + q = query; + var results = fuse.search(query, { limit: 20 }); + items = results + .filter((x) => x.score <= 0.75) + .map((x) => x.item); + if (items.length === 0) { + items = [{ dir: "Sorry 😿", previous_headings: "", title: "No results found.", what: "No results found.", path: window.location.href }]; + } + } + callback(items); } - } - callback(items); -} - $("#search-input").autocomplete(options, [ - { - name: "content", - source: searchFuse, - templates: { - suggestion: (s) => { - if (s.title == s.what) { - return `${s.dir} >
${s.title}
`; - } else if (s.previous_headings == "") { - return `${s.dir} >
${s.title}
> ${s.what}`; - } else { - return `${s.dir} >
${s.title}
> ${s.previous_headings} > ${s.what}`; - } + $("#search-input").autocomplete(options, [ + { + name: "content", + source: searchFuse, + templates: { + suggestion: (s) => { + if (s.title == s.what) { + return `${s.dir} >
${s.title}
`; + } else if (s.previous_headings == "") { + return `${s.dir} >
${s.title}
> ${s.what}`; + } else { + return `${s.dir} >
${s.title}
> ${s.previous_headings} > ${s.what}`; + } + }, }, }, - }, - ]).on('autocomplete:selected', function(event, s) { - window.location.href = s.path + "?q=" + q + "#" + s.id; - }); + ]).on('autocomplete:selected', function (event, s) { + window.location.href = s.path + "?q=" + q + "#" + s.id; + }); }); })(window.jQuery || window.$) -document.addEventListener('keydown', function(event) { +document.addEventListener('keydown', function (event) { // Check if the pressed key is '/' if (event.key === '/') { event.preventDefault(); // Prevent any default action associated with the '/' key diff --git a/docs/pkgdown.yml b/docs/pkgdown.yml index 678677e..9900562 100644 --- a/docs/pkgdown.yml +++ b/docs/pkgdown.yml @@ -1,12 +1,12 @@ -pandoc: '3.4' -pkgdown: 2.1.3 +pandoc: 3.8.2.1 +pkgdown: 2.2.0 pkgdown_sha: ~ articles: ClimateSmart: ClimateSmart.html GlobalFishingWatch: GlobalFishingWatch.html MultipleUse: MultipleUse.html spatialplanr: spatialplanr.html -last_built: 2025-06-18T02:23Z +last_built: 2025-11-18T01:06Z urls: reference: https://mathmarecol.github.io/spatialplanr/reference article: https://mathmarecol.github.io/spatialplanr/articles diff --git a/docs/reference/CoralSeaVelocity.html b/docs/reference/CoralSeaVelocity.html index 14c6586..d856143 100644 --- a/docs/reference/CoralSeaVelocity.html +++ b/docs/reference/CoralSeaVelocity.html @@ -7,7 +7,7 @@ spatialplanr - 0.6.9 + 0.7.0