% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/ops.R
\name{st_apply}
\alias{st_apply}
\alias{st_apply.stars}
\title{st_apply apply a function to one or more array dimensions}
\usage{
\method{st_apply}{stars}(
  X,
  MARGIN,
  FUN,
  ...,
  CLUSTER = NULL,
  PROGRESS = FALSE,
  FUTURE = FALSE,
  rename = TRUE,
  .fname,
  single_arg = has_single_arg(FUN, list(...)) || can_single_arg(FUN),
  keep = FALSE
)
}
\arguments{
\item{X}{object of class \code{stars}}

\item{MARGIN}{see \link[base]{apply}; index number(s) or name(s) of the dimensions over which \code{FUN} will be applied}

\item{FUN}{see \link[base]{apply} and see Details.}

\item{...}{arguments passed on to \code{FUN}}

\item{CLUSTER}{cluster to use for parallel apply; see \link[parallel]{makeCluster}}

\item{PROGRESS}{logical; if \code{TRUE}, use \code{pbapply::pbapply} to show progress bar}

\item{FUTURE}{logical;if \code{TRUE}, use \code{future.apply::future_apply}}

\item{rename}{logical; if \code{TRUE} and \code{X} has only one attribute and 
\code{FUN} is a simple function name, rename the attribute of the returned object 
to the function name}

\item{.fname}{function name for the new attribute name (if one or more 
dimensions are reduced) or the new dimension (if a new dimension is created); 
if missing, the name of \code{FUN} is used}

\item{single_arg}{logical; if \code{TRUE}, FUN takes a single argument (like \code{fn_ndvi1} below), 
if \code{FALSE} FUN takes multiple arguments (like \code{fn_ndvi2} below).}

\item{keep}{logical; if \code{TRUE}, preserve dimension metadata (e.g. time stamps)}
}
\value{
object of class \code{stars} with accordingly reduced number of dimensions; 
in case \code{FUN} returns more than one value, a new dimension is created carrying 
the name of the function used; see the examples. Following the logic of 
\link[base]{apply}, This new dimension is put before the
other dimensions; use \link{aperm} to rearrange this, see last example.
}
\description{
st_apply apply a function to array dimensions: aggregate over space, time, or something else
}
\details{
FUN is a function which either operates on a single object, which will 
be the data of each iteration step over dimensions MARGIN, or a function that 
has as many arguments as there are elements in such an object. See the NDVI 
examples below. The second form can be VERY much faster e.g. when a trivial 
function is not being called for every pixel, but only once (example).

The heuristics for the default of \code{single_arg} work often, but not always; try
setting this to the right value when \code{st_apply} gives an error.
}
\examples{
tif = system.file("tif/L7_ETMs.tif", package = "stars")
x = read_stars(tif)
st_apply(x, 1:2, mean) # mean band value for each pixel
st_apply(x, c("x", "y"), mean) # equivalent to the above
st_apply(x, 3, mean)   # mean of all pixels for each band
\dontrun{
 st_apply(x, "band", mean) # equivalent to the above
 st_apply(x, 1:2, range) # min and max band value for each pixel
 fn_ndvi1 = function(x) (x[4]-x[3])/(x[4]+x[3]) # ONE argument: will be called for each pixel
 fn_ndvi2 = function(red,nir) (nir-red)/(nir+red) # n arguments: will be called only once
 ndvi1 = st_apply(x, 1:2, fn_ndvi1)
   # note that we can select bands 3 and 4 in the first argument:
 ndvi2 = st_apply(x[,,,3:4], 1:2, fn_ndvi2) 
 all.equal(ndvi1, ndvi2)
 # compute the (spatial) variance of each band; https://github.com/r-spatial/stars/issues/430
 st_apply(x, 3, function(x) var(as.vector(x))) # as.vector is required!
 # to get a progress bar also in non-interactive mode, specify:
 if (require(pbapply)) { # install it, if FALSE
   pboptions(type = "timer")
 }
 st_apply(x, 1:2, range) # dimension "range" is first; rearrange by:
 st_apply(x, 1:2, range) |> aperm(c(2,3,1))
}
}
