转换栅格值

Transform raster values

我用它来预测光栅堆栈上的值,但这些值随后需要进行反向转换,因为它们是对数值:

r_pred <- raster::predict(model=rf_model, object=raster_stack)

我试过了(但没用):

values(r_pred) <- exp(r_pred)

Reclassify() 看起来很有希望,但我不确定从哪里开始?

简短的回答是:您可能只需使用:

r_back_transformed = exp(r_pred)

长答案来自 values 文档:

In most cases it is better to use getValues rather than values. values is typically used in functions after a read* function has been used and it will return all the values that happen to be in memory at that point, or fail if there are no values in memory. In contrast getValues will read values from disk if necessary.

所以您可以使用raster::getValues()raster::setValues()的组合。如:

raster::setValues(r_pred) <- exp(raster::getValues(r_pred))

不过,在大多数情况下你可以直接使用calc or stackApply functions。例如:

r_back_transformed = raster::calc(r_pred, exp)  

exp函数应用于r_pred的所有层。

但是,对于许多函数,栅格代数是本机实现的;来自 raster documentation chapter four: raster algebra):

Many generic functions that allow for simple and elegant raster algebra have been implemented for Raster* objects, including the normal algebraic operators such as +, -, *, /, logical operators such as >, >=, <, ==, !} and functions such as abs, round, ceiling, floor, trunc, sqrt, log, log10, exp, cos, sin, max, min, range, prod, sum, any, all. In these functions you can mix raster objects with numbers, as long as the first argument is a raster object.

你可以使用 r_back_transformed = exp(r_pred).

最后,terra::values()对应raster::getValues()/raster::setValues(),可以解释你最初的直觉,而terra,替代raster,原生支持一些 raster algebra。对于 non-natively 支持的函数,terra::app 映射到 raster::calc.

hrvg 的答案很好,但我想简化它并添加另一种方法,并用示例数据(来自?预测)进行说明;并使用 terra(但这也适用于 raster

示例数据

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))

模型和模型预测

library(randomForest)
rfmod <- randomForest(pa ~., data=v)
r_pred <- predict(logo, rfmod)

你现在可以back-transform(我实际上并没有转换输入)这样的结果

p <- exp(r_pred)

可以这样用一行表达

p <- predict(logo, rfmod) |> exp()

您也可以像下面那样做,但不推荐这样做,因为它效率较低且内存不安全

v <- exp(values(r_pred))
p <- setValues(r_pred, v)

# or overwrite the values like this
# values(r_pred) <- exp(values(r_pred)) 

或使用应用程序(calc with terra)

p <- app(r_pred, exp) 
# p <- calc(r_pred, exp)  # with raster

或者,您可以围绕预测函数编写自己的包装器,并在那里处理转换;但在这种情况下,这似乎有些矫枉过正。

f <- function(model, data, ...) {
    exp(predict(model, data, ...))
}
p <- predict(logo, rfmod, fun=f)