Reputation: 359
Question: How do I format the 'const' argument for the predict function in the Terra package?
Background and details:
I am using Terra's predict function to create spatial maps from a model. The function worked as expected when I created full rasters for my three constant values. When I saw predict has an argument 'const' for constants, I decided to use that instead. Unfortunately, the help document doesn't specify how to structure the data beyond that they should be in a dataframe.
Argument description for 'const' from ?terra::predict
:
data.frame. Can be used to add a constant value as a predictor variable so that you do not need to make a SpatRaster layer for it
The argument is not used in any of the examples listed at the bottom of the document either.
What I tried:
I tried formating the dataframe as a single row with named columns for each constant value that is required in the model. The function accepted it with the warning:
Warning messages: 1: In data.frame(..., check.names = FALSE) : row names were found from a short variable and have been discarded
But this produced clearly incorrect values in the resulting outputs. Possibly it was just using the first value for all three constants, but I don't know.
I also tried formating the dataframe with two columns, one for the variable name and one for the variable values. This failed with the following error:
Error in h(simpleError(msg, call)) : error in evaluating the argument 'x' in selecting a method for function 'writeRaster': arguments imply differing number of rows: 10000, 3
10000 may be referring to the dimenions of the raster data (10k x 10k) and the 3 is likely referring to the three rows in the constant dataframe I supplied.
I don't want to go back to writing rasters for each constant because I am producing many maps and each one would require 3 10k x 10k rasters to be generated with the constant values, which is time consuming and may lead to memory issues.
Any suggestions would be greatly appreciated!
Upvotes: 2
Views: 287
Reputation: 47481
Here is an illustration
library(terra)
logo <- rast(system.file("ex/logo.tif", package="terra"))
names(logo) <- c("red", "green", "blue")
p <- matrix(c(48, 48, 48, 53, 50, 46, 54, 70, 84, 85, 74, 84, 95, 85, 66, 42, 26, 4, 19, 17, 7, 14, 26, 29, 39, 45, 51, 56, 46, 38, 31, 22, 34, 60, 70, 73, 63, 46, 43, 28), ncol=2)
a <- matrix(c(22, 33, 64, 85, 92, 94, 59, 27, 30, 64, 60, 33, 31, 9, 99, 67, 15, 5, 4, 30, 8, 37, 42, 27, 19, 69, 60, 73, 3, 5, 21,37, 52, 70, 74, 9, 13, 4, 17, 47), ncol=2)
xy <- rbind(cbind(1, p), cbind(0, a))
e <- extract(logo, xy[,2:3])
v <- data.frame(cbind(pa=xy[,1], e))
model <- glm(formula=pa~., data=v)
names(model$coefficients)[-1]
#[1] "red" "green" "blue"
names(logo)
#[1] "red" "green" "blue"
# standard approach
r <- predict(logo, model)
# one or more constants
r <- predict(logo[[2:3]], model, const=data.frame(red=0))
r <- predict(logo$blue, model, const=data.frame(red=100, green=0))
# you could even use constants only
x <- logo[[1]]
names(x) <- "A"
r <- predict(x, model, const=data.frame(blue=50, red=100, green=0))
The output is as expected:
predict(model, data.frame(blue=50, red=100, green=0))
# 1
#-4.538653
r[1]
# A
#1 -4.538653
Upvotes: 2