Fails to run `superClass` when one of the raster layer is factor
I am trying to run superClass with a raster stack having both numeric and categorical layers. But it returns me the following error:
Error: variable 'Class' was fitted with type "numeric" but type "factor" was supplied
But if I use caret package directly for model building, the model runs fine. By default caret converts factor variable using one hot encoding. Here is a minimal, reproducible example
library(terra)
library(RStoolbox)
f <- system.file("ex/elev.tif", package="terra")
elevation <- rast(f)
slope <- terrain(elevation, "slope")
aspect <- terrain(elevation, "aspect")
plot(elevation)
#Make the aspect categorical
m_aspect <- c(-Inf, -1, 1,
-1, 22.5, 2,
22.5, 67.5, 3,
67.5, 112.5, 4,
112.5, 157.5, 5,
157.5, 202.5, 6,
202.5, 247.5, 7,
247.5, 292.5, 8,
292.5, 337.5, 9,
337.5, Inf, 2)
rclmat_aspect <- matrix(m_aspect, ncol=3, byrow=TRUE)
rc_aspect <- classify(aspect, rclmat_aspect, include.lowest=TRUE)
plot(rc_aspect)
aspect_classes <- data.frame(Value = 1:9,
Class = c("Flat", "N","NE","E","SE","S","SW","W",
"NW"))
levels(rc_aspect) <- aspect_classes
logo <- c(elevation, slope, rc_aspect)
p <- read.table(text = "Longitude Latitude
49.60 6.00
49.65 6.10
49.70 6.15
49.75 6.20
49.80 6.25
49.85 6.27
49.87 5.80
49.90 5.83
50.00 5.85
50.05 5.90", header = T)
a <- p + 0.01
pb <- c(rep("Yes", nrow(p)), rep("No", nrow(a)))
pts <- cbind(pb, rbind(p, a))
sp.pts <- terra::vect(pts, geom=c("Latitude", "Longitude"), crs=crs(elevation))
v <- terra::extract(logo, sp.pts, xy = T, ID = F, bind=T)
## Fit classifier (splitting training into 70% training data, 30% validation data)
rf_mod <- superClass(logo, trainData = sf::st_as_sf(v),
responseCol = "pb",
model = "rf", tuneLength = 1, trainPartition = 0.7,
predict = T,
predType = "prob", #for class probabilities
mode = "classification",
kfold = 3, na.rm=TRUE)
@bappa10085 You are correct, caret converts it, however, terra does not. I am first using terra::predict before feeding anything into caret which seems to have some problems with factors. I will investigate on that, thanks for reporting. For now, just convert your SpatRaster Class (the values of it) to numeric before it then gets coverted by caret again to factors. As follows:
logo$Class <- as.numeric(logo$Class)
rf_mod <- superClass(logo,
trainData = sf::st_as_sf(v),
responseCol = "pb",
model = "rf",
tuneLength = 1,
trainPartition = 0.7,
predict = T,
predType = "prob", #for class probabilities
mode = "classification",
kfold = 3, na.rm=TRUE)
plot(rf_mod$map)