对栅格中的每个像元应用函数会返回错误

问题描述 投票:0回答:1

我有一个标准化值的函数

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
r function raster terra
1个回答
0
投票

你的函数的问题在于它不是向量化

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)

© www.soinside.com 2019 - 2024. All rights reserved.