Title: | Mask Species Geographic Ranges |
---|---|
Description: | Mask ranges based on expert knowledge or remote sensing layers. These tools can be combined to quantitatively and reproducibly generate a new map or to update an existing map. Methods include expert opinion and data-driven tools to generate thresholds for binary masks. |
Authors: | Cory Merow [aut, cre], Peter J. Galante [aut], Jamie M. Kass [aut], Cecina Babich Morrow [aut], Valentina Grisales Betancur [aut] |
Maintainer: | Cory Merow <[email protected]> |
License: | GPL-3 |
Version: | 1.1 |
Built: | 2025-01-21 04:14:57 UTC |
Source: | https://github.com/cran/maskRangeR |
Annotate point data with rasters based on matching dates associated with points to dates associated with rasters. Specifically, we're thinking of the points as species observations and the rasters as remotely sensed environmental layers, but they can represent any points and rasters with dates.
annotate(datedOccs, env, envDates, dateScale)
annotate(datedOccs, env, envDates, dateScale)
datedOccs |
a 'SpatialPointsDataFrame' of occurrence localities (generally longitude and latitude in decimal degrees) paired with dates. One column must be labeled 'date' and have class 'POSIXct', e.g., as obtained from using 'lubridate::parse_date_time' |
env |
a raster stack |
envDates |
a vector of dates the same length as 'env'. The vector should have class 'POSIXct', e.g., as obtained from using 'lubridate::parse_date_time' |
dateScale |
string: 'year', 'month', or 'day' |
See Examples.
a SpatialPointsDataFrame
Cory Merow <[email protected]>,
r1 <- raster::raster(nrows=50, ncols=50, xmn=-50, xmx=50) raster::values(r1)<- runif(n = (50*50)) r2 <- raster::raster(nrows=50, ncols=50, xmn=-50, xmx=50) raster::values(r2)<- runif(n = (50*50)) env <- raster::stack(r1,r2) names(env) <- c("1995","1996") datedOccs <- data.frame(cbind(c(0,10), c(-10,15))) colnames(datedOccs) <- c("long", "lat") datedOccs$date <- c("1995", "1996") datedOccs$date <- lubridate::parse_date_time(datedOccs$date, orders = c("Y", "Ym")) sp::coordinates(datedOccs) <- c("long", "lat") raster::projection(datedOccs) <- raster::projection(env) dateScale = "year" envDates <- c("1995","1996") annotate(datedOccs = datedOccs, env = env, envDates = envDates, dateScale = dateScale)
r1 <- raster::raster(nrows=50, ncols=50, xmn=-50, xmx=50) raster::values(r1)<- runif(n = (50*50)) r2 <- raster::raster(nrows=50, ncols=50, xmn=-50, xmx=50) raster::values(r2)<- runif(n = (50*50)) env <- raster::stack(r1,r2) names(env) <- c("1995","1996") datedOccs <- data.frame(cbind(c(0,10), c(-10,15))) colnames(datedOccs) <- c("long", "lat") datedOccs$date <- c("1995", "1996") datedOccs$date <- lubridate::parse_date_time(datedOccs$date, orders = c("Y", "Ym")) sp::coordinates(datedOccs) <- c("long", "lat") raster::projection(datedOccs) <- raster::projection(env) dateScale = "year" envDates <- c("1995","1996") annotate(datedOccs = datedOccs, env = env, envDates = envDates, dateScale = dateScale)
The use case envision is updating a binary map to continuous values that describe the proportion of the cell that is suitable, based on land use/land cover classes
continuousMask(contStack, suitable, binaryRange, maskValue = NA, ...)
continuousMask(contStack, suitable, binaryRange, maskValue = NA, ...)
contStack |
a stack of layers with continuous values. |
suitable |
a vector of names of suitable layers of 'contStack'. These can be substrings of the layer names that can be 'grep'ped from 'names(contStack)' |
binaryRange |
a binary raster |
maskValue |
numeric. The value in 'binaryRange' that indicates the unsuitable cell |
... |
arguments to be passed to 'raster::mask' |
See Examples.
a raster
Cory Merow <[email protected]>,
Obtain the same extents and resample to the finest resolution layer.
cropResampleTrim(expertMap, maskListRaw)
cropResampleTrim(expertMap, maskListRaw)
expertMap |
A binary map, either as a polygon or a raster. |
maskListRaw |
A list of rasters, each corresponding to layers from which masks will eventually be made (in another function). |
See Examples.
a list
Cory Merow <[email protected]>,
r1 <- raster::raster(raster::extent(c(-72, -64, 41, 50)), res = c(0.008333333, 0.008333333)) raster::values(r1) <- (1:raster::ncell(r1))^2 coords <- dismo::randomPoints(r1, 4) polyg <- sp::SpatialPolygons(list(sp::Polygons(list(sp::Polygon(coords)),1))) r2 <- raster::raster(raster::extent(c(-72, -64, 41, 50)), res = c(0.008333333, 0.008333333)) raster::values(r2) <- (1:raster::ncell(r2))^3 r3 <- raster::raster(raster::extent(c(-72, -64, 41, 50)), res = c(0.008333333, 0.008333333)) raster::values(r3) <- (1:raster::ncell(r3))^0.5 maskListRaw <- list(r1, r2, r3) cropResampleTrim(expertMap = polyg, maskListRaw = maskListRaw)
r1 <- raster::raster(raster::extent(c(-72, -64, 41, 50)), res = c(0.008333333, 0.008333333)) raster::values(r1) <- (1:raster::ncell(r1))^2 coords <- dismo::randomPoints(r1, 4) polyg <- sp::SpatialPolygons(list(sp::Polygons(list(sp::Polygon(coords)),1))) r2 <- raster::raster(raster::extent(c(-72, -64, 41, 50)), res = c(0.008333333, 0.008333333)) raster::values(r2) <- (1:raster::ncell(r2))^3 r3 <- raster::raster(raster::extent(c(-72, -64, 41, 50)), res = c(0.008333333, 0.008333333)) raster::values(r3) <- (1:raster::ncell(r3))^0.5 maskListRaw <- list(r1, r2, r3) cropResampleTrim(expertMap = polyg, maskListRaw = maskListRaw)
Aids in exploring how different focal regions may affect masks.
focalCompare(layer, windowSizes, fun, mc.cores = 1)
focalCompare(layer, windowSizes, fun, mc.cores = 1)
layer |
A single raster layer to be summarized. |
windowSizes |
A vector of the number of cell in each direction to buffer for the focal summary. E.g., a value of 1 indicates the 8 cells immediately surrounding the focal cell, i.e., which are 1 cell away. |
fun |
The function fun should take multiple numbers, and return a single number. For example mean, modal, min or max. It should also accept a na.rm argument (or ignore it, e.g. as one of the 'dots' arguments. For example, length will fail, but function(x, ...)na.omit(length(x)) works. (Specifications from 'raster::focal') |
mc.cores |
Number of cores for (optional) parallelization |
See Examples.
Raster object
This may be particularly useful if for mobile species when their movement patterns cover a much larger extent than the single cell in which they were observed.
Cory Merow <[email protected]>,
r <- raster::raster(ncols=36, nrows=18, xmn=0) r[] <- runif(raster::ncell(r)) r15 <- focalCompare(r, windowSizes = c(1:5),mc.cores=1,fun=mean)
r <- raster::raster(ncols=36, nrows=18, xmn=0) r[] <- runif(raster::ncell(r)) r15 <- focalCompare(r, windowSizes = c(1:5),mc.cores=1,fun=mean)
Based on a potential distribution, environmental rasters, and bounds for suitable habitat on the environmental rasters
lotsOfMasks(expertRaster, maskStack, maskBounds)
lotsOfMasks(expertRaster, maskStack, maskBounds)
expertRaster |
The binary expert map (1s and 0s), rasterized with the same projection as 'maskStack' |
maskStack |
A stack of *named* layers from which masks will be made |
maskBounds |
A data.frame with columns indicating the layer name (matching the names in maskStack), and the min and max values of that layer to be used for masking. |
See Examples.
a RasterStack
Cory Merow <[email protected]>,
r1 <- raster::raster(nrows=108, ncols=21, xmn=0, xmx=10) raster::values(r1)<- sort(runif(n = (108*21))) r1[r1>0.5] <- 1 r1[r1<0.5] <- 0 r2 <- raster::raster(nrows=108, ncols=21, xmn=0, xmx=10) raster::values(r2) <- runif(n=(108*21)) r3 <- raster::raster(nrows=108, ncols=21, xmn=0, xmx=10) raster::values(r3) <- runif(n=(108*21)) maskStack <- raster::stack(r2, r3) names(maskStack) <- c("r2", "r3") minbounds <- c(0.3, 0.4) maxbounds <- c(0.4, 0.5) maskBounds <- data.frame(cbind(c("r2", "r3"), minbounds, maxbounds)) colnames(maskBounds)<- c("Layer", "Min Value", "Max Value") maskBounds[,2] <- as.numeric(as.character(maskBounds[,2])) maskBounds[,3] <- as.numeric(as.character(maskBounds[,3])) out <- lotsOfMasks(expertRaster = r1, maskStack = maskStack, maskBounds = maskBounds)
r1 <- raster::raster(nrows=108, ncols=21, xmn=0, xmx=10) raster::values(r1)<- sort(runif(n = (108*21))) r1[r1>0.5] <- 1 r1[r1<0.5] <- 0 r2 <- raster::raster(nrows=108, ncols=21, xmn=0, xmx=10) raster::values(r2) <- runif(n=(108*21)) r3 <- raster::raster(nrows=108, ncols=21, xmn=0, xmx=10) raster::values(r3) <- runif(n=(108*21)) maskStack <- raster::stack(r2, r3) names(maskStack) <- c("r2", "r3") minbounds <- c(0.3, 0.4) maxbounds <- c(0.4, 0.5) maskBounds <- data.frame(cbind(c("r2", "r3"), minbounds, maxbounds)) colnames(maskBounds)<- c("Layer", "Min Value", "Max Value") maskBounds[,2] <- as.numeric(as.character(maskBounds[,2])) maskBounds[,3] <- as.numeric(as.character(maskBounds[,3])) out <- lotsOfMasks(expertRaster = r1, maskStack = maskStack, maskBounds = maskBounds)
Compare how masks of climate tolerances affect predicted area
manyMaskSensitivity(crt, rasProj = NULL, maskBounds, expertRaster)
manyMaskSensitivity(crt, rasProj = NULL, maskBounds, expertRaster)
crt |
A raster stack; the output from the function maskRangeR::cropResampleTrim |
rasProj |
(optional) a character string: a proj4string showing the projection of the environmental layers. If NULL, areas will be estimated using the raster package. |
maskBounds |
A data.frame with columns indicating the layer name (matching the names in maskStack), and the min and max values of that layer to be used for masking. |
expertRaster |
The binary expert map (1s and 0s), rasterized with the same projection as 'maskStack' |
See Examples.
returns a data.frame where row names are the environmental layer name combinations, and Area is expressed in square km, unless a projection is supplied
Peter Galante <[email protected]>
#See lotsOfMasks and maskRanger examples
#See lotsOfMasks and maskRanger examples
Performs data driven masking of potential species distributions.
maskRanger( potentialDist, initialDist = NULL, maskLayers, logicString, method = "mask" )
maskRanger( potentialDist, initialDist = NULL, maskLayers, logicString, method = "mask" )
potentialDist |
A raster stack of binary or continuous values. Supplying more than one layer will be interepreted as different time periods. Layers should follow the naming convention 'Y2000', 'Y2001', etc. Must have same extent and resolution as maskLayers. |
initialDist |
A raster showing a previously created optimally tuned SDM. Must have same extent and resolution as maskLayers. |
maskLayers |
A single raster or a raster stack. If a single raster, the same mask will be applied to each layer of 'potentialDist'. If a stack it must have the same number of layers as potentialDist, and each layer corresponds to a different time period. Must have same extent and resolution as initialDist. |
logicString |
a character indicating the logical conditions to use for masking. |
method |
A list of strings defining methods to be used, in the same order as 'rsList'. If a single value is provided it will be applied to all rasters in 'rsList'. Options currently include only 'mask' to mask cells with values outside the bounds. |
See Examples.
a raster stack
To apply multiple masks, e.g., elevation and forest cover, use separate calls to maskRS.
Cory Merow <[email protected]>,
# Multiple Expert Maps # Generate random polygon env1 <- raster::raster(nrows=108, ncols=21, xmn=0, xmx=10) env2 <- raster::raster(nrows=108, ncols=21, xmn=0, xmx=10) env3 <- raster::raster(nrows=108, ncols=21, xmn=0, xmx=10) raster::values(env1)<- sort(runif(n = (108*21))) raster::values(env2)<- runif(n = (108*21)) raster::values(env3)<- runif(n = (108*21)) sdm <- raster::raster(nrows=108, ncols=21, xmn=0, xmx=10) raster::values(sdm)<- sort(runif(n = (108*21))) coords <- dismo::randomPoints(sdm, 3) polyg <- sp::Polygon(coords) polyg <- sp::SpatialPolygons(list(sp::Polygons(list(polyg), ID = "a"))) expertRaster <- raster::rasterize(polyg, sdm) maskStack <-raster:: stack(env1, env2, env3) names(maskStack) <- c("env1", "env2", "env3") # Get list of tolerances for environmental data env1Vals <- quantile(raster::values(env1), prob = c(0, 0.025, 0.25, 0.5, 0.75, 0.975, 1), na.rm = TRUE) env2Vals <- quantile(raster::values(env2), prob = c(0, 0.025, 0.25, 0.5, 0.75, 0.975, 1), na.rm = TRUE) env3Vals <- quantile(raster::values(env3), prob = c(0, 0.025, 0.25, 0.5, 0.75, 0.975, 1), na.rm = TRUE) maskBounds <- data.frame(rbind(cbind(env1Vals[[3]], env1Vals[[5]]), cbind(env2Vals[[3]], env2Vals[[5]]), cbind(env3Vals[[3]], env3Vals[[5]]))) maskBounds <- cbind(names(maskStack), maskBounds) colnames(maskBounds) <- c("Layer", "min", "max") # mask range by these tolerance masks realized <- lotsOfMasks(expertRaster, maskStack, maskBounds)
# Multiple Expert Maps # Generate random polygon env1 <- raster::raster(nrows=108, ncols=21, xmn=0, xmx=10) env2 <- raster::raster(nrows=108, ncols=21, xmn=0, xmx=10) env3 <- raster::raster(nrows=108, ncols=21, xmn=0, xmx=10) raster::values(env1)<- sort(runif(n = (108*21))) raster::values(env2)<- runif(n = (108*21)) raster::values(env3)<- runif(n = (108*21)) sdm <- raster::raster(nrows=108, ncols=21, xmn=0, xmx=10) raster::values(sdm)<- sort(runif(n = (108*21))) coords <- dismo::randomPoints(sdm, 3) polyg <- sp::Polygon(coords) polyg <- sp::SpatialPolygons(list(sp::Polygons(list(polyg), ID = "a"))) expertRaster <- raster::rasterize(polyg, sdm) maskStack <-raster:: stack(env1, env2, env3) names(maskStack) <- c("env1", "env2", "env3") # Get list of tolerances for environmental data env1Vals <- quantile(raster::values(env1), prob = c(0, 0.025, 0.25, 0.5, 0.75, 0.975, 1), na.rm = TRUE) env2Vals <- quantile(raster::values(env2), prob = c(0, 0.025, 0.25, 0.5, 0.75, 0.975, 1), na.rm = TRUE) env3Vals <- quantile(raster::values(env3), prob = c(0, 0.025, 0.25, 0.5, 0.75, 0.975, 1), na.rm = TRUE) maskBounds <- data.frame(rbind(cbind(env1Vals[[3]], env1Vals[[5]]), cbind(env2Vals[[3]], env2Vals[[5]]), cbind(env3Vals[[3]], env3Vals[[5]]))) maskBounds <- cbind(names(maskStack), maskBounds) colnames(maskBounds) <- c("Layer", "min", "max") # mask range by these tolerance masks realized <- lotsOfMasks(expertRaster, maskStack, maskBounds)
rangeSVM()
returns a tuned support vector machine (SVM) model that predicts
species identity based on predictors that are solely spatial, based on occurrence coordinates,
or a combination of spatial and environmental, based on both occurrence coordinates and
environmental suitability values. Suitability values can be predicted with species distribution
models (SDMs; a.k.a. ecological niche models).
rangeSVM(xy1, xy2, ..., sdm = NULL, nrep = 100, weight = FALSE, mc.cores = 1)
rangeSVM(xy1, xy2, ..., sdm = NULL, nrep = 100, weight = FALSE, mc.cores = 1)
xy1 |
Matrix or data frame of occurrence coordinates for species 1. |
xy2 |
Matrix or data frame of occurrence coordinates for species 2. |
... |
Other matrices or data frames of occurrence coordinates for additional species. |
sdm |
Raster or RasterStack representing environmental suitability (can be predictions from SDMs). These must have the same extent as both species' occurrence points. Default is NULL. |
nrep |
Numeric for number of SVM tuning iterations. Default is 100. |
weight |
Boolean. If TRUE, species with fewer occurrence records are weighted higher in the SVM. Default is FALSE. |
mc.cores |
Number of cores to use for parallel processing. Default is 1. |
The tuning operation uses tune.svm()
from the e1071 package, which performs 10-fold
cross validation and selects the best model based on classification error. Ranges of the cost and gamma
parameters are explored in the tuning exercise. The tuning function is iterated nrep
times, and the
parameter combination used most frequently across all iterations is used to build a final SVM model.
When sdm = NULL
, the SVM is purely spatial, based only on the occurrence coordinates of
each species. Otherwise, the SVM is fit with both a spatial predictor and any additional ones added as
rasters. These extra predictors can be based on predictions from a species distribution model
(SDM; a.k.a. ecological niche model), and in this case would represent environmental or climatic
suitability, depending on the variables used in the SDM.
The tuned SVM model.
r1.sdm <- raster::raster(raster::extent(c(-72, -64, 41, 50)), res = c(0.008333333, 0.008333333)) raster::values(r1.sdm) <- (1:raster::ncell(r1.sdm))^2 r2.sdm <- raster::raster(raster::extent(c(-72, -64, 41, 50)), res = c(0.008333333, 0.008333333)) raster::values(r2.sdm) <- (raster::ncell(r2.sdm):1)^2 r3.sdm <- raster::raster(raster::extent(c(-72, -64, 41, 50)), res = c(0.008333333, 0.008333333)) r3.sdm [1] <- 10 r3.sdm <- raster::distance(r3.sdm) sp1.xy <- data.frame(dismo::randomPoints(r1.sdm, 15, prob = TRUE)) colnames(sp1.xy) <- c("longitude", "latitude") sp2.xy <- data.frame(dismo::randomPoints(r2.sdm, 15, prob = TRUE)) colnames(sp2.xy) <- c("longitude", "latitude") sp3.xy <- data.frame(dismo::randomPoints(r3.sdm, 15, prob = TRUE)) colnames(sp3.xy) <- c("longitude", "latitude") # Spatial SVMs (this can take about a minute to run) svm.SP <- rangeSVM(sp1.xy, sp2.xy, sp3.xy, nrep=5) # more reps are recommended
r1.sdm <- raster::raster(raster::extent(c(-72, -64, 41, 50)), res = c(0.008333333, 0.008333333)) raster::values(r1.sdm) <- (1:raster::ncell(r1.sdm))^2 r2.sdm <- raster::raster(raster::extent(c(-72, -64, 41, 50)), res = c(0.008333333, 0.008333333)) raster::values(r2.sdm) <- (raster::ncell(r2.sdm):1)^2 r3.sdm <- raster::raster(raster::extent(c(-72, -64, 41, 50)), res = c(0.008333333, 0.008333333)) r3.sdm [1] <- 10 r3.sdm <- raster::distance(r3.sdm) sp1.xy <- data.frame(dismo::randomPoints(r1.sdm, 15, prob = TRUE)) colnames(sp1.xy) <- c("longitude", "latitude") sp2.xy <- data.frame(dismo::randomPoints(r2.sdm, 15, prob = TRUE)) colnames(sp2.xy) <- c("longitude", "latitude") sp3.xy <- data.frame(dismo::randomPoints(r3.sdm, 15, prob = TRUE)) colnames(sp3.xy) <- c("longitude", "latitude") # Spatial SVMs (this can take about a minute to run) svm.SP <- rangeSVM(sp1.xy, sp2.xy, sp3.xy, nrep=5) # more reps are recommended
rangeSVM_predict()
returns a raster representing the ranges of the species
predicted by the fitted SVM tuned with rangeSVM()
.
rangeSVM_predict(svm, r, sdm = NULL)
rangeSVM_predict(svm, r, sdm = NULL)
svm |
Model object for the SVM, returned by |
r |
Raster with the extent desired for the prediction. The values for cells used for predictions must have non-NA values, but the particular values do not matter. |
sdm |
Raster or RasterStack representing environmental suitability (can be predictions from SDMs). These rasters must match the predictor variables used in the SVM. Default is NULL. |
The values of the output raster are 1, 2, ..., corresponding to xy1, xy2, and any additional species used in rangeSVM()
.
These values represent the identities of the species.
The Raster representing the SVM predictions.
r1.sdm <- raster::raster(raster::extent(c(-72, -64, 41, 50)), res = c(0.008333333, 0.008333333)) raster::values(r1.sdm) <- (1:raster::ncell(r1.sdm))^2 r2.sdm <- raster::raster(raster::extent(c(-72, -64, 41, 50)), res = c(0.008333333, 0.008333333)) raster::values(r2.sdm) <- (raster::ncell(r2.sdm):1)^2 r3.sdm <- raster::raster(raster::extent(c(-72, -64, 41, 50)), res = c(0.008333333, 0.008333333)) r3.sdm [1] <- 10 r3.sdm <- raster::distance(r3.sdm) sp1.xy <- data.frame(dismo::randomPoints(r1.sdm, 15, prob = TRUE)) colnames(sp1.xy) <- c("longitude", "latitude") sp2.xy <- data.frame(dismo::randomPoints(r2.sdm, 15, prob = TRUE)) colnames(sp2.xy) <- c("longitude", "latitude") sp3.xy <- data.frame(dismo::randomPoints(r3.sdm, 15, prob = TRUE)) colnames(sp3.xy) <- c("longitude", "latitude") # Spatial SVMs (this can take about a minute to run) svm.SP <- rangeSVM(sp1.xy, sp2.xy, sp3.xy, nrep=5) # Use SVM to create a raster of predicted regions rand_svm.SP <- rangeSVM_predict(svm = svm.SP, r = r1.sdm)
r1.sdm <- raster::raster(raster::extent(c(-72, -64, 41, 50)), res = c(0.008333333, 0.008333333)) raster::values(r1.sdm) <- (1:raster::ncell(r1.sdm))^2 r2.sdm <- raster::raster(raster::extent(c(-72, -64, 41, 50)), res = c(0.008333333, 0.008333333)) raster::values(r2.sdm) <- (raster::ncell(r2.sdm):1)^2 r3.sdm <- raster::raster(raster::extent(c(-72, -64, 41, 50)), res = c(0.008333333, 0.008333333)) r3.sdm [1] <- 10 r3.sdm <- raster::distance(r3.sdm) sp1.xy <- data.frame(dismo::randomPoints(r1.sdm, 15, prob = TRUE)) colnames(sp1.xy) <- c("longitude", "latitude") sp2.xy <- data.frame(dismo::randomPoints(r2.sdm, 15, prob = TRUE)) colnames(sp2.xy) <- c("longitude", "latitude") sp3.xy <- data.frame(dismo::randomPoints(r3.sdm, 15, prob = TRUE)) colnames(sp3.xy) <- c("longitude", "latitude") # Spatial SVMs (this can take about a minute to run) svm.SP <- rangeSVM(sp1.xy, sp2.xy, sp3.xy, nrep=5) # Use SVM to create a raster of predicted regions rand_svm.SP <- rangeSVM_predict(svm = svm.SP, r = r1.sdm)
Measure a number of reasonable thresholds and calculate areas based on these thresholds
thresholdSensitivity( datedOccs, maskLayer, maskClass, sdm, maskProjection = NULL, maskVal = NULL, selectedValue = NULL )
thresholdSensitivity( datedOccs, maskLayer, maskClass, sdm, maskProjection = NULL, maskVal = NULL, selectedValue = NULL )
datedOccs |
a 'SpatialPointsDataFrame' where one column is labeled 'date' and has class 'POSIXct', e.g., as obtained from using 'lubridate::parse_date_time' |
maskLayer |
the layer from which you will build the mask. Usually the most recent satellite derived raster |
maskClass |
either top5, aroundSelected, quants, or userSpecified. "top5" ranks the environmental values at occurrences and returns the 5 highest observed values."aroundSelected" selects two observed values above and two below a user-specified threshold value. "quants" returns quantile values as thresholds. "userSpecified" will take a list of values defined by the user. |
sdm |
previously generated species distribution model |
maskProjection |
(optional) a proj4string showing the projection of the maskLayer. If NULL, areas will be estimated using the raster package. |
maskVal |
(optional) a user defined value for thresholding when using the "aroundSelected" maskClass, or if "userSpecified", a list of thresholds to use. |
selectedValue |
(optional) a user selected value around which masks will be selected using the nearest two threshold on either side |
See Examples.
returns a list containing two items. The first is a rasterstack of the masked distributions. The second item is a table of thresholds and areas
Peter Galante <[email protected]>