I created a random forest model in R, and want to apply it to a SpatRaster object using the predict
function in terra. I could transform the raster to a data.frame instead of predicting directly on the SpatRaster, however my actual dataset is too large for that.
A reproducible example:
library(terra)
library(ranger)
r <- rast(ncols=95, nrows=90, nlyrs=5, crs="+proj=longlat",
xmin=5.74167, xmax=6.5333, ymin=49.44167, ymax=50.19167,
names=c("band1","band2","band3","band4","band5"))
# Fill the raster with random values
set.seed(123)
r$band1 <- runif(n = ncell(r))
r$band2 <- init(r, "cell")
r$band3 <- sample(1:10, ncell(r), replace = T)
r$band4 <- sample(1:10, ncell(r), replace = T)
r$band5 <- sample(1:10, ncell(r), replace = T)
# Extract some random raster values as training data
extr_values <- spatSample(r, 10)
extr_values$response <- as.factor(sample(c(1,2), nrow(extr_values), replace = T))
# Model
rf_model <- ranger(response ~., data = extr_values, num.trees = 50)
# Prediction
prediction <- predict(r, rf_model, na.rm = TRUE)$predictions
I have tried different types of models (e.g. randomForest package), different rasters and sets of coordinates. Even stranger, I ran old scripts that performed similar tasks and that used to run, they all produce the same error. Maybe linked to a recent update of terra? Any help would be greatly appreciated.
The output of ranger::predict
is a list. That is not what is expected.
p <- predict(rf_model, r[1:2])
str(p)
#List of 5
# $ predictions : Factor w/ 1 level "1": 1 1
# $ num.trees : num 500
# $ num.independent.variables: num 5
# $ num.samples : int 2
# $ treetype : chr "Classification"
# - attr(*, "class")= chr "ranger.prediction"
You are interested in the "predictions". To get these values into the output raster, you need to provide a custom predict function.
pfun <- \(...) {
predict(...)$predictions
}
p <- predict(r, rf_model, fun=pfun, na.rm = TRUE)