% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/app.r
\name{app,GRaster-method}
\alias{app,GRaster-method}
\alias{app}
\alias{appFuns}
\alias{appCheck,GRaster,character-method}
\alias{appCheck}
\title{Apply a function to a set of rasters}
\usage{
\S4method{app}{GRaster}(x, fun, datatype = "auto", seed = NULL)

appFuns(warn = TRUE)

\S4method{appCheck}{GRaster,character}(x, fun, msgOnGood = TRUE, failOnBad = TRUE)
}
\arguments{
\item{x}{A \code{GRaster} with one or more named layers.}

\item{fun}{Character: The function to apply. This must be written as a character string that follows these rules:
\itemize{
\item It must use typical arithmetic operators like \code{+}, \code{-}, \code{*}, \code{/} and/or functions that can be seen using \code{appFuns(TRUE)}.
\item The \code{\link[=names]{names()}} of the rasters do not match any of the functions in the \code{appFuns(TRUE)} table. Note that \code{x} and \code{y} are forbidden names :(
}

The help page for \strong{GRASS} tool \code{r.mapcalc} will be especially helpful. You can see this page using \code{grassHelp("r.mapcalc")}.}

\item{datatype}{Character: This ensures that rasters are treated as a certain type before they are operated on. This is useful when using rasters that have all integer values, which \strong{GRASS} can assume represent integers, even if they are not supposed to. In this case, the output of operations on this raster might be an integer if otherwise not corrected. Partial matching is used, and options include:
\itemize{
\item \code{"integer"}: Force all rasters to integers by truncating their values. The output may still be of type \code{float} if the operation creates non-integer values.
\item \code{"float"}: Force rasters to be considered floating-point values.
\item \code{"double"}: Force rasters to be considered double-floating point values.
\item \code{"auto"} (default): Ensure that rasters are represented by their native \code{\link[=datatype]{datatype()}} (i.e., "CELL" rasters as integers, "FCELL" rasters as floating-point, and "DCELL" as double-floating point).
}}

\item{seed}{Numeric integer vector or \code{NULL} (default): A number for the random seed. Used only for \code{app()} function \code{rand()}, that generates a random number. If \code{NULL}, a seed will be generated. Defining the seed is useful for replicating a raster made with \code{rand()}. This must be an integer!}

\item{warn}{Logical (function \code{appFuns()}): If \code{TRUE} (default), display a warning when \code{allFuns()} is not called interactively.}

\item{msgOnGood}{Logical (function \code{appCheck()}): If \code{TRUE} (default), display a message if no overt problems with the raster names and formula are detected.}

\item{failOnBad}{Logical (function \code{appCheck()}): If \code{TRUE} (default), fail if overt problems with raster names and the formula are detected.}
}
\value{
A \code{GRaster}.
}
\description{
\code{app()} applies a function to a set of "stacked" rasters. It is similar to the \code{\link[terra:app]{terra::app()}} and \code{\link[terra:lapp]{terra::lapp()}} functions.

\code{appFuns()} provides a table of \strong{GRASS} functions that can be used by \code{app()} and their equivalents in \strong{R}.

\code{appCheck()} tests whether a formula supplied to \code{app()} has any "forbidden" function calls.

The \code{app()} function operates in a manner somewhat different from \code{\link[terra:app]{terra::app()}}. The function to be applied \emph{must} be written as a character string. For example, if the \code{GRaster} had layer names "\code{x1}" and "\code{x2}", then the function might be like \code{"= max(sqrt(x1), log(x2))"}. Rasters \strong{cannot} have the same names as functions used in the formula. In this example, the rasters could not be named "max", "sqrt", or "log". Note that the name of a \code{GRaster} is given by \code{\link[=names]{names()}}--this can be different from the name of the object in \strong{R}.

The \code{app()} function will automatically check for \code{GRaster} names that appear also to be functions that appear in the formula. However, you can check a formula before running \code{app()} by using the \code{appCheck()} function. You can obtain a list of \code{app()} functions using \code{appFuns()}. Note that these are sometimes different from how they are applied in \strong{R}.

Tips:
\itemize{
\item Make sure your \code{GRaster}s have \code{names()}. The function matches on these, not the name of the variable you use in \strong{R} for the \code{GRaster}.
\item Use \code{null()} instead of \code{NA}, and use \code{isnull()} instead of \code{is.na()}.
\item If you want to calculate values using while ignoring \code{NA} (or \code{null}) values, see the functions that begin with \code{n} (like \code{nmean}).
\item Be mindful of the data type that a function returns. In \strong{GRASS}, these are \code{CELL} (integer), \code{FCELL} (floating point values--precise to about the 7th decimal place), and \code{DCELL} (double-floating point values--precise to about the 15th decimal place; commensurate with the \strong{R} \code{numeric} type). In cases where you want a \code{GRaster} to be treated like a float or double type raster, wrap the name of the \code{GRaster} in the \code{float()} or \code{double()} functions. This is especially useful if the \code{GRaster} might be assumed to be the \code{CELL} type because it only contains integer values. You can get the data type of a raster using \code{\link[=datatype]{datatype()}} with the \code{type} argument set to \code{GRASS}. You can change the data type of a \code{GRaster} using \code{\link[=as.int]{as.int()}}, \code{\link[=as.float]{as.float()}}, and \code{\link[=as.doub]{as.doub()}}. Note that categorical rasters are really \code{CELL} (integer) rasters with an associated "levels" table. You can also change a \code{CELL} raster to a \code{FCELL} raster by adding then subtracting a decimal value, as in \code{x - 0.1 + 0.1}. See \code{vignette("GRasters", package = "fasterRaster")}.
\item The \code{rand()} function returns integer values by default. If you want non-integer values, use the tricks mentioned above to datatype non-integer values. For example, if you want uniform random values in the range between 0 and 1, use something like \verb{= float(rand(0 + 0.1, 1 + 0.1) - 0.1)}.
\item \code{GRaster}s with short names can cause the function to mis-specify the formula in \strong{GRASS}. This happens when, for example, the \code{fun} argument contains an "if" statement, and the raster name is "i" or "f", which would incorrectly replace those letters in the "if" with the \strong{GRASS} name of the raster. To avoid this, avoid using short raster names that could be part of longer operators using by \code{app()} (see \code{\link[=appFuns]{appFuns()}} for a list of these operators).
}
}
\examples{
if (grassStarted()) {

# Setup
library(terra)

# Elevation raster
madElev <- fastData("madElev")

# Convert SpatRaster to a GRaster:
elev <- fast(madElev)

# Create a "stack" of rasters for us to operate on:
x <- c(elev, elev^2, sqrt(elev))

# Demonstrate check for badly-named rasters:
names(x) <- c("cos", "asin", "exp")
fun <- "= cos / asin + exp"
appCheck(x, fun, failOnBad = FALSE)

# Rename rasters acceptable names and run the function:
names(x) <- c("x1", "x2", "x3")
fun <- "= (x1 / x2) + x3"
appCheck(x, fun, failOnBad = FALSE)
app(x, fun = fun)

# This is the same as:
(x[[1]] / x[[2]]) + x[[3]]

# We can view a table of app() functions using appFuns():
appFuns()

# We can also get the same table using:
data(appFunsTable)

# Apply other functions:
fun <- "= median(x1 / x2, x3, x1 * 2, cos(x2))"
app(x, fun = fun)

fun <- "= round(x1) * tan(x2) + log(x3, 10)"
app(x, fun = fun)

# Demonstrate effects of data type:
fun <- "= x1 + x3"
app(x, fun = fun, datatype = "float") # output is floating-point
app(x, fun = fun, datatype = "integer") # output is integer

# Some functions override the "datatype" argument:
fun <- "= sin(x2)"
app(x, fun = fun, datatype = "integer")

# Make a raster with random values [1:4], with equal probability of each:
fun <- "= round(rand(0.5, 4.5))"
rand <- app(elev, fun = fun)
rand

freqs <- freq(rand) # cell frequencies
print(freqs)

}
}
\seealso{
\code{\link[terra:app]{terra::app()}}, \code{\link[terra:lapp]{terra::lapp()}}, \code{\link[=subst]{subst()}}, \code{\link[=classify]{classify()}}, and especially the \strong{GRASS} manual page for tool \code{r.mapcalc} (see \code{grassHelp("r.mapcalc")})
}
