R: Compute focal values with an iterating C++ function

focalCpp {terra} | R Documentation

## Compute focal values with an iterating C++ function

### Description

Calculate focal values with a C++ function that iterates over cells to speed up computations by avoiding an R loop (with apply).

See `focal` for an easier to use method.

### Usage

    ## S4 method for signature 'SpatRaster'
    focalCpp(x, w=3, fun, ..., fillvalue=NA,
    		expand=FALSE, filename="", overwrite=FALSE, wopt=list())

### Arguments

`x` | SpatRaster
`w` | window. The window can be defined as one (for a square) or two numbers (row, col); or with an odd-sized weights matrix. See the Details section in `focal`
`fun` | `cppFunction` that iterates over cells. For C++ functions that operate on a single focal window, or for R functions use `focal` instead. The function must have at least three arguments. The first argument can have any name, but it must be a NumericVector or std::vector<double> and gets the focal values. The other two arguments `ni` and `wi` must be of type `size_t`. `ni` represents the number of cells and `nw` represents the size of (number of elements in) the window
`...` | additional arguments to `fun`
`fillvalue` | numeric. The value of the cells in the virtual rows and columns outside of the raster
`expand` | logical. If `TRUE` The value of the cells in the virtual rows and columns outside of the raster are set to be the same as the value on the border
`filename` | character. Output filename
`overwrite` | logical. If `TRUE`, `filename` is overwritten
`wopt` | additional arguments for writing files as in `writeRaster`

### Value

SpatRaster

### See Also

`focal`, `focalValues`

### Examples

    ## Not run:
    library(Rcpp)
    cppFunction(
    	'NumericVector sum_and_multiply(NumericVector x, double m, size_t ni, size_t nw) {
    		NumericVector out(ni);
    		// loop over cells
    		for (size_t i=0; i<ni; i++) {
    			// compute something for a window
    			size_t start = i * nw;
    			double v = 0;
    			// loop over the values of a window
    			for (size_t j=start; j<(start+nw); j++) {
    				v += x[j];
    			}
    			out[i] = v * m;
    		}
    		return out;
    	}'
    )

    nr <- nc <- 10
    r <- rast(ncols=nc, nrows=nr, ext= c(0, nc, 0, nr))
    values(r) <- 1:ncell(r)

    raw <- focalCpp(r, w=3, fun=sum_and_multiply, fillvalue=0, m=10)

    # same as
    f1 <- focal(r, w=3, fun=sum, fillvalue=0) *10
    all(values(f1) == values(raw))

    # and as
    ffun <- function(x, m) { sum(x) * m }
    f2 <- focal(r, w=3, fun=ffun, fillvalue=0, m=10)

    # You can also use an R function with focalCpp but this
    # is not recommended

    R_sm_iter <- function(x, m, ni, nw) {
    	out <- NULL
    	for (i in 1:ni) {
    		start <- (i-1) * nw + 1
    		out[i] <- sum(x[start:(start+nw-1)]) * m
    	}
    	out
    }

    fr <- focalCpp(r, w=3, fun=R_sm_iter, fillvalue=0, m=10)

    ## End(Not run)

[Package terra version 1.4-22 Index]