# Apply a function to the cells of a SpatRaster

`app.Rd`

Apply a function to the values of each cell of a SpatRaster. Similar to `apply`

-- think of each layer in a SpatRaster as a column (or row) in a matrix.

This is generally used to summarize the values of multiple layers into one layer; but this is not required.

`app`

calls function `fun`

with the raster data as first argument. Depending on the function supplied, the raster data is represented as either a matrix in which each layer is a column, or a vector representing a cell. The function should return a vector or matrix that is divisible by ncell(x). Thus, both "sum" and "rowSums" can be used, but "colSums" cannot be used.

You can also apply a function `fun`

across datasets by layer of a `SpatRasterDataset`

. In that case, summarization is by layer across SpatRasters.

## Arguments

- x
SpatRaster or SpatRasterDataset

- fun
a function that operates on a vector or matrix. This can be a function that is defined in base-R or in a package, or a function you write yourself (see examples). Functions that return complex output (e.g. a list) may need to be wrapped in your own function to simplify the output to a vector or matrix. The following functions have been re-implemented in C++ for speed: "sum", "mean", "median", "modal", "which", "which.min", "which.max", "min", "max", "prod", "any", "all", "sd", "std", "first". To use the base-R function for say, "min", you could use something like

`fun=function(i) min(i)`

or the equivalent`fun = \(i) min(i)`

- ...
additional arguments for

`fun`

. These are typically numerical constants. They should *never* be another SpatRaster- cores
positive integer. If

`cores > 1`

, a 'parallel' package cluster with that many cores is created and used. You can also supply a cluster object. Ignored for functions that are implemented by terra in C++ (see under fun)- filename
character. Output filename

- overwrite
logical. If

`TRUE`

,`filename`

is overwritten- wopt
list with named options for writing files as in

`writeRaster`

## Details

To speed things up, parallelization is supported, but this is often not helpful, and it may actually be slower. There is only a speed gain if you have many cores (> 8) and/or a very complex (slow) function `fun`

. If you write `fun`

yourself, consider supplying a `cppFunction`

made with the Rcpp package instead (or go have a cup of tea while the computer works for you).

## See also

`lapp`

, `tapp`

, `Math-methods`

, `roll`

## Examples

```
r <- rast(ncols=10, nrows=10)
values(r) <- 1:ncell(r)
x <- c(r, sqrt(r), r+50)
s <- app(x, fun=sum)
s
#> class : SpatRaster
#> dimensions : 10, 10, 1 (nrow, ncol, nlyr)
#> resolution : 36, 18 (x, y)
#> extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 (CRS84) (OGC:CRS84)
#> source(s) : memory
#> name : sum
#> min value : 53
#> max value : 260
# for a few generic functions like
# "sum", "mean", and "max" you can also do
sum(x)
#> class : SpatRaster
#> dimensions : 10, 10, 1 (nrow, ncol, nlyr)
#> resolution : 36, 18 (x, y)
#> extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 (CRS84) (OGC:CRS84)
#> source(s) : memory
#> name : sum
#> min value : 53
#> max value : 260
## SpatRasterDataset
sd <- sds(x, x*2, x/3)
a <- app(sd, max)
a
#> class : SpatRaster
#> dimensions : 10, 10, 3 (nrow, ncol, nlyr)
#> resolution : 36, 18 (x, y)
#> extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 (CRS84) (OGC:CRS84)
#> source(s) : memory
#> names : lyr.1, lyr.1, lyr.1
#> min values : 2, 2, 102
#> max values : 200, 20, 300
# same as
max(x, x*2, x/3)
#> class : SpatRaster
#> dimensions : 10, 10, 3 (nrow, ncol, nlyr)
#> resolution : 36, 18 (x, y)
#> extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 (CRS84) (OGC:CRS84)
#> source(s) : memory
#> names : lyr.1, lyr.1, lyr.1
#> min values : 2, 2, 102
#> max values : 200, 20, 300
# and as (but slower)
b <- app(sd, function(i) max(i))
## also works for a single layer
f <- function(i) (i+1) * 2 * i + sqrt(i)
s <- app(r, f)
# same as above, but that is not memory-safe
# and has no filename argument
s <- f(r)
if (FALSE) {
#### multiple cores
test0 <- app(x, sqrt)
test1 <- app(x, sqrt, cores=2)
testfun <- function(i) { 2 * sqrt(i) }
test2 <- app(x, fun=testfun, cores =2)
## this fails because testfun is not exported to the nodes
# test3 <- app(x, fun=function(i) testfun(i), cores=2)
## to export it, add it as argument to fun
test3 <- app(x, fun=function(i, ff) ff(i), cores =3, ff=testfun)
}
```