我有一个标准化值的函数
norm_formula <- function(x, min_value, max_value){
if(is.na(x)){
norm_x <- NA
} else if(is.nan(x)) {
norm_x <- NA
} else {
if(x < min_value){
norm_x <- 1
} else if (x > max_value){
norm_x <- 100
} else {
norm_x <- (100-1)*((x - min_value)/(max_value - min_value)) + 1
}
}
return(norm_x)
}
我想将此函数应用到 spatraster 中的每个单元格
library(terra)
r <- rast(ncol=3, nrow=2)
values(r) <- 1:ncell(r)
s <- app(r, fun= function(x) norm_formula(x, 0, 0.5))
Error in if (is.na(x)) { : the condition has length > 1
你的函数的问题在于它不是向量化
norm_formula(1:10, 1, 10)
#Error in if (is.na(x)) { : the condition has length > 1
这是矢量化版本
norm_vect <- function(x, min_value, max_value){
i <- x < min_value
j <- x > max_value
norm_x <- (100-1)*((x - min_value)/(max_value - min_value)) + 1
norm_x[i] <- 1
norm_x[j] <- 100
norm_x
}
你可以看到它有效
norm_vect(1:10, 2, 5)
# [1] 1 1 34 67 100 100 100 100 100 100
并与
app
一起使用
s <- app(r, fun=\(x) norm_vect(x, 0, 4))
这里有两种可能的选择。您需要检查它们是否确实按预期工作。如果是这样,
f2
可能是最有效的。
f1 <- function(r, min_value, max_value) {
ifel(r < min_value, 1,
ifel(r > max_value, 100,
99 * ((r - min_value)/(max_value - min_value)) + 1))
}
a <- f1(r, 0, 4)
f2 <- function(r, min_value, max_value) {
y <- clamp(r, min_value, max_value)
(100-1)*((y - min_value)/(max_value - min_value)) + 1
}
b <- f2(r, 0, 4)