Apply a user-defined R function over (multi-band) pixel time series
Description
Create a proxy data cube, which applies a user-defined R function over all pixel time series of a data cube. In contrast to reduce_time, the time dimension is not reduced, i.e., resulting time series must have identical length as the input data cube but may contain a different number of bands / variables. Example uses of this function may include time series decompositions, cumulative sums / products, smoothing, sophisticated NA filling, or similar.
optional character vector to specify band names for the output cube
keep_bands
logical; keep bands of input data cube, defaults to FALSE, i.e., original bands will be dropped
FUN
user-defined R function that is applied on all pixel time series (see Details)
load_pkgs
logical or character; if TRUE, all currently attached packages will be attached automatically before executing FUN in spawned R processes, specific packages can alternatively be provided as a character vector.
load_env
logical or environment; if TRUE, the current global environment will be restored automatically before executing FUN in spawned R processes, can be set to a custom environment.
…
not used
Details
FUN receives a single (multi-band) pixel time series as a matrix with rows corresponding to bands and columns corresponding to time. In general, the function must return a matrix with the same number of columns. If the result contains only a single band, it may alternatively return a vector with length identical to the length of the input time series (number of columns of the input).
This function returns a proxy object, i.e., it will not start any computations besides deriving the shape of the result.
Examples
# create image collection from example Landsat data only # if not already done in other examplesif (!file.exists(file.path(tempdir(), "L8.db"))) { L8_files <-list.files(system.file("L8NY18", package ="gdalcubes"),".TIF", recursive =TRUE, full.names =TRUE)create_image_collection(L8_files, "L8_L1TP", file.path(tempdir(), "L8.db"), quiet =TRUE) }L8.col =image_collection(file.path(tempdir(), "L8.db"))v =cube_view(extent=list(left=388941.2, right=766552.4, bottom=4345299, top=4744931, t0="2018-01", t1="2018-06"),srs="EPSG:32618", nx =497, ny=526, dt="P1M")L8.cube =raster_cube(L8.col, v) L8.cube =select_bands(L8.cube, c("B04", "B05")) L8.ndvi =apply_pixel(L8.cube, "(B05-B04)/(B05+B04)", "NDVI")# Apply a user defined R functionL8.ndvi.resid =apply_time(L8.ndvi, names="NDVI_residuals", FUN=function(x) { y = x["NDVI",]if (sum(is.finite(y)) <3) {return(rep(NA,ncol(x))) } t =1:ncol(x)return(predict(lm(y ~ t)) - x["NDVI",]) })L8.ndvi.resid
A data cube proxy object
Dimensions:
low high count pixel_size chunk_size
t 2018-01-01 2018-06-30 6 P1M 6
y 4345299 4744931 526 759.756653992395 384
x 388941.2 766552.4 497 759.781086519115 384
Bands:
name offset scale nodata unit
1 NDVI_residuals 0 1 NaN
# apply_time.cubeApply a user-defined R function over (multi-band) pixel time series```{r include=FALSE}library(gdalcubes)```## DescriptionCreate a proxy data cube, which applies a user-defined R function over all pixel time series of a data cube. In contrast to [`reduce_time`](reduce_time.Rmd), the time dimension is not reduced, i.e., resulting time seriesmust have identical length as the input data cube but may contain a different number of bands / variables.Example uses of this function may include time series decompositions, cumulative sums / products, smoothing, sophisticatedNA filling, or similar.## Usage```rapply_time.cube( x,names =NULL,keep_bands =FALSE, FUN,load_pkgs =FALSE,load_env =FALSE, ...)```## Arguments| Argument | Description ||:------------|:----------------------------------|| x | source data cube || names | optional character vector to specify band names for the output cube || keep_bands | logical; keep bands of input data cube, defaults to FALSE, i.e., original bands will be dropped || FUN | user-defined R function that is applied on all pixel time series (see Details) || load_pkgs | logical or character; if TRUE, all currently attached packages will be attached automatically before executing FUN in spawned R processes, specific packages can alternatively be provided as a character vector. || load_env | logical or environment; if TRUE, the current global environment will be restored automatically before executing FUN in spawned R processes, can be set to a custom environment. || ... | not used |## DetailsFUN receives a single (multi-band) pixel time series as a matrix with rows corresponding to bands and columns corresponding to time.In general, the function must return a matrix with the same number of columns. If the result contains only a single band, it may alternatively return a vector with length identical to the length of the input time series (number of columns of the input).For more details and examples on how to write user-defined functions, please refer to the gdalcubes website at [https://gdalcubes.github.io/source/concepts/udfs.html](https://gdalcubes.github.io/source/concepts/udfs.html).## Valuea proxy data cube object## NoteThis function returns a proxy object, i.e., it will not start any computations besides deriving the shape of the result.## Examples```{r}# create image collection from example Landsat data only # if not already done in other examplesif (!file.exists(file.path(tempdir(), "L8.db"))) { L8_files <-list.files(system.file("L8NY18", package ="gdalcubes"),".TIF", recursive =TRUE, full.names =TRUE)create_image_collection(L8_files, "L8_L1TP", file.path(tempdir(), "L8.db"), quiet =TRUE) }L8.col =image_collection(file.path(tempdir(), "L8.db"))v =cube_view(extent=list(left=388941.2, right=766552.4, bottom=4345299, top=4744931, t0="2018-01", t1="2018-06"),srs="EPSG:32618", nx =497, ny=526, dt="P1M")L8.cube =raster_cube(L8.col, v) L8.cube =select_bands(L8.cube, c("B04", "B05")) L8.ndvi =apply_pixel(L8.cube, "(B05-B04)/(B05+B04)", "NDVI")# Apply a user defined R functionL8.ndvi.resid =apply_time(L8.ndvi, names="NDVI_residuals", FUN=function(x) { y = x["NDVI",]if (sum(is.finite(y)) <3) {return(rep(NA,ncol(x))) } t =1:ncol(x)return(predict(lm(y ~ t)) - x["NDVI",]) })L8.ndvi.residplot(L8.ndvi.resid)```