Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Support for terra's SpatRaster objects #15

Merged
merged 1 commit into from
Apr 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ Depends: R (>= 3.5.0)
Imports: caret, stats, utils, ggplot2, graphics, reshape, FNN, plyr, zoo, methods, grDevices, data.table, lattice
Suggests: doParallel, randomForest, lubridate, raster, sp, knitr, mapview,
rmarkdown, sf, scales, parallel, latticeExtra, virtualspecies, gridExtra,
viridis, rgeos, stars, scam
RoxygenNote: 7.1.0
viridis, rgeos, stars, scam, terra
RoxygenNote: 7.1.1
VignetteBuilder: knitr
12 changes: 11 additions & 1 deletion R/aoa.R
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#' variable importance of the machine learning algorithm used for model training.
#' The AOA is derived by applying a threshold on the DI which is the (outlier-removed)
#' maximum DI of the cross-validated training data.
#' @param newdata A RasterStack, RasterBrick or data.frame containing the data
#' @param newdata A RasterStack, RasterBrick, SpatRaster or data.frame containing the data
#' the model was meant to make predictions for.
#' @param model A train object created with caret used to extract weights from (based on variable importance) as well as cross-validation folds
#' @param cl A cluster object e.g. created with doParallel. Should only be used if newdata is large.
Expand Down Expand Up @@ -119,12 +119,20 @@ aoa <- function(newdata,
}
}
as_stars <- FALSE
as_terra <- FALSE
if (inherits(newdata, "stars")) {
if (!requireNamespace("stars", quietly = TRUE))
stop("package stars required: install that first")
newdata = methods::as(newdata, "Raster")
as_stars <- TRUE
}

if (inherits(newdata, "SpatRaster")) {
if (!requireNamespace("terra", quietly = TRUE))
stop("package terra required: install that first")
newdata = methods::as(newdata, "Raster")
as_terra <- TRUE
}
#### Prepare output as either as RasterLayer or vector:
out <- NA
if (inherits(newdata, "Raster"))
Expand Down Expand Up @@ -299,6 +307,8 @@ aoa <- function(newdata,
out <- raster::stack(out,AOA)
if (as_stars)
out <- split(stars::st_as_stars(out), "band")
if(as_terra)
out = methods::as(out, "SpatRaster")
}else{
out <- DI_out
AOA <- rep(1,length(out))
Expand Down
15 changes: 15 additions & 0 deletions R/calibrate_aoa.R
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
calibrate_aoa <- function(AOA,model, window.size=5, calib="scam",multiCV=FALSE,
length.out = 10, maskAOA=TRUE, showPlot=TRUE,k=6,m=2){
as_stars <- FALSE
as_terra <- FALSE
if (inherits(AOA, "stars")) {
if (!requireNamespace("stars", quietly = TRUE))
stop("package stars required: install that first")
Expand All @@ -72,6 +73,15 @@ calibrate_aoa <- function(AOA,model, window.size=5, calib="scam",multiCV=FALSE,
as_stars <- TRUE
}

if (inherits(AOA, "SpatRaster")) {
if (!requireNamespace("terra", quietly = TRUE))
stop("package terra required: install that first")
attr <- attributes(AOA)[c("aoa_stats","TrainDI")]
AOA <- methods::as(AOA, "Raster")
attributes(AOA)<- c(attributes(AOA),attr)
as_terra <- TRUE
}

if(multiCV){
preds_all <- data.frame()
train_predictors <- model$trainingData[,-which(names(model$trainingData)==".outcome")]
Expand Down Expand Up @@ -274,6 +284,11 @@ calibrate_aoa <- function(AOA,model, window.size=5, calib="scam",multiCV=FALSE,
AOA <- split(stars::st_as_stars(AOA), "band")
attributes(AOA)<- c(attributes(AOA),attr)
}

if(as_terra){
AOA <- methods::as(AOA, "SpatRaster")
attributes(AOA)<- c(attributes(AOA),attr)
}
names(AOA)[names(AOA)=="expectedError"] <- paste0("expected_",model$metric)
#return(AOA)

Expand Down
2 changes: 1 addition & 1 deletion man/aoa.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

71 changes: 71 additions & 0 deletions vignettes/terra-showcase.Rmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
title: "Showcase with terra SpatRaster"
date: "`r Sys.Date()`"
output:
rmarkdown::html_document:
toc: true
theme: united
vignette: >
%\VignetteIndexEntry{Showcase with terra SpatRaster}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---

```{r setup, echo=FALSE}
knitr::opts_chunk$set(fig.width = 8.83)
```

---

# Introduction

This vignette is meant to showcase that the CAST package now is able to handle
terra SpatRaster objects. Changes to the code were implemented only in the `aoa()` and
`calibrate_aoa()` function and are restricted to coercing a SpatRaster input
to a RasterStack as well as coercing the output back to SpatRaster.
Below is a minimal example based on the AOA-tutorial vignette.

```{r message = FALSE, warning=FALSE}
library(CAST)
library(terra)
library(raster)
library(lubridate)
library(methods)
```

```{r}
predictors_sp <- stack(system.file("extdata","predictors_2012-03-25.grd",package="CAST"))
data <- get(load(system.file("extdata","Cookfarm.RData",package="CAST")))
trainDat <- data[data$altitude==-0.3&
year(data$Date)==2012&
week(data$Date)%in%c(10:12),]

library(caret)
predictors <- c("DEM","TWI","Precip_cum","cday",
"MaxT_wrcc","Precip_wrcc","BLD",
"Northing","Easting","NDRE.M")
set.seed(10)
model <- train(trainDat[,predictors],trainDat$VW,
method="rf",tuneGrid=data.frame("mtry"=2),
importance=TRUE,ntree=50,
trControl=trainControl(method="cv",number=3))
```

From here we will coerce the Raster object to SpatRaster objects to show
that the aoa and calibrate_aoa functions work on SpatRasters as well. The
application might not make sense on a thematic level. The example was drafted
just to show that the functions accept and return SpatRaster objects.

```{r}
predictors_terra = as(predictors_sp, "SpatRaster")
AOA <- aoa(predictors_terra, model)
class(AOA)
attributes(AOA)$aoa_stats
```

```{r}
AOA_calib <- calibrate_aoa(AOA,model,window.size = 5,length.out = 5, multiCV=TRUE,showPlot=FALSE)
class(AOA_calib$AOA)
AOA_calib$plot
```