#' Create one GRaster layer per unique value in a GRaster
#'
#' @description This function creates a multi-layered `GRaster` for every unique values in an input `GRaster`. By default, the output will have a value of 1 wherever the input has the given value, and 0 elsewhere. This is useful for creating dummy variable `GRaster` layers for use with models that have factors, especially if the input `GRaster` is categorical. Note that the [predict()] function in **fasterRaster** usually does not need this treatment of `GRaster`s since it can handle categorical rasters already.
#'
#' @param x A `GRaster`.
#'
#' @param classes Either `NULL` (default) or a character vector with category labels for which to create outputs. If the input is not a categorical/factor or `integer` `GRaster`, this is ignored.
#'
#' @param keep Logical: If `FALSE` (default), then the original value in the input `GRaster` will be retained in the each of the output `GRaster` layers wherever the input had the respective value. Other cells will be assigned a value of `other`.
#'
#' @param other Numeric or `NA`: Value to assign to cells that do not have the target value.
#'
#' @param bins Numeric: Number of bins in which to put values. This is only used for `GRaster`s that are not categorical/factor rasters or `integer` rasters.
#'
#' @param digits Numeric: Number of digits to which to round input if it is a `numeric` or `double` `GRaster` (see `vignettes("GRasters", package = "fasterRaster")`).
#'
#' @returns If the input `x` is a single-layered `GRaster`, the output will be a multi-layered `GRaster` with one layer per value in the input, or one layer per values in `classes`. If the input is a multi-layered `GRaster`, the output will be a `list` of multi-layered `GRaster`s.
#'
#' @example man/examples/ex_segregate.r
#'
#' @seealso [terra::segregate()]
#'
#' @aliases segregate
#' @rdname segregate
#' @exportMethod segregate
methods::setMethod(
f = "segregate",
signature = c(x = "GRaster"),
function(x, classes = NULL, keep = FALSE, other = 0, bins = 100, digits = 3) {
.locationRestore(x)
.region(x)
if (!is.null(classes) & (all(is.factor(x)) | all(is.integer(x)))) x <- x[x %in% classes]
if (is.na(other)) other <- "null()"
out <- list()
nLayers <- nlyr(x)
for (i in seq_len(nLayers)) {
# unique values
dtype <- datatype(x, type = "GRASS")[i]
freqs <- freq(x[[i]], digits = digits, bins = bins)
freqs <- freqs[count > 0]
vals <- freqs$value
nVals <- length(vals)
if (nVals == 0) {
thisOut <- NA
} else {
thisSrcs <- .makeSourceName("segregate", "raster", nVals)
for (j in seq_len(nVals)) {
if (keep) {
thisKeep <- vals[j]
} else {
thisKeep <- 1
}
ex <- paste0(thisSrcs[j], " = if(", sources(x)[i], " == ", vals[j], ", ", thisKeep, ", ", other, ")")
rgrass::execGRASS("r.mapcalc", expression = ex, flags = c(.quiet(), "overwrite"))
}
names <- if (is.factor(x)[i]) {
freqs[[3]]
} else {
as.character(vals)
}
thisOut <- .makeGRaster(thisSrcs, names = names)
}
out[[i]] <- thisOut
}
if (nLayers == 1L) {
out <- out[[1L]]
} else {
names(out) <- names(x)
}
out
} # EOF
)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.