使用 ifelse 在 r 中叠加栅格以满足三种不同的条件
Overlay rasters in r to meet three different conditions using ifelse
我正在尝试 运行 带有栅格的叠加函数,我希望在每个像元处满足所有 3 个不同的条件(使用 ==
和 >
或 <
运算符)并生成单个栅格作为输出。
运行 ifelse
与 &
运算符似乎以线性方式从左到右查看条件 - 如果满足前两个条件,则它将产生if 条件作为输出,不管第三个条件。 &&
此处不能使用,因为结果未向量化。
您可以在下面的示例中看到这一点,其中生成的栅格很明显没有评估所有三个参数。第一条线索是,即使在第三个栅格中某些值是 NA,它也会产生结果。
我想我可以通过首先检查 x 和 y 的条件然后用这个结果分别用不同的函数检查 z 的条件来得到我想要的结果,但我希望能够做到这一切在一个函数中(至少看起来这应该是可能的)。
希望有人能指出我正确的方向。
library(raster)
fn <- system.file("external/test.grd", package="raster")
s <- stack(fn, fn,fn)
#Create grids
s[[1]] <- round(runif(ncell(s), 1, 2))
s[[2]] <- round(runif(ncell(s), 1, 2))
s[[3]] <- round(runif(ncell(s), 1, 2))
#convert some values in s[[3]] to NA
s[[3]][s[[3]] == 1]<- NA
#run overlay function
result.rast <- overlay(s[[1]], s[[2]], s[[3]], fun =
function(x,y,z) {
ifelse( x == 2 & y == 1 & z ==2, 1, 0)
} )
你试过了吗stackApply
?
您还可以将栅格堆栈的每一层用作矢量。
这是一个示例(不过,这可能是引用 rasterStack 中的单元格的更好方法)
tt <- raster(ncol=4,nrow=5)
tt[] <- 1
tts <- stack(tt,tt,tt)
tts[[1]][4,2]<-NA
# now the condition
tt2 <- (tts[[1]] == 1 & tts[[2]] == 1 & tts[[3]] == 1)
plot(tt2)
我没有看到没有使用第三个条件的证据。 NA 值是一个特例。请参阅函数 f2
了解您可以执行的一些操作。
使用较小的栅格更容易看到发生了什么
library(raster)
set.seed(0)
r <- raster(ncol=10, nrow=10, xmn=0, xmx=10, ymn=0, ymx=10)
r1 <- setValues(r, round(runif(ncell(r), 1, 2)))
r2 <- setValues(r, round(runif(ncell(r), 1, 2)))
r3 <- setValues(r, round(runif(ncell(r), 1, 2)))
r3[r3 == 1] <- NA
s <- stack(r1, r2, r3)
res1 <- overlay(s, fun =
function(x,y,z) {
ifelse( x == 2 & y == 1 & z ==2, 1, 0)
} )
#A more complex function, that keeps NAs
f2 <- function(x,y,z) {
a <- rep(0, length(x))
a[x == 2 & y == 1 & z ==2] <- 1
a[is.na(x) | is.na(y) | is.na(z)] <- NA
a
}
res2 <- overlay(s, fun = f2)
我正在尝试 运行 带有栅格的叠加函数,我希望在每个像元处满足所有 3 个不同的条件(使用 ==
和 >
或 <
运算符)并生成单个栅格作为输出。
运行 ifelse
与 &
运算符似乎以线性方式从左到右查看条件 - 如果满足前两个条件,则它将产生if 条件作为输出,不管第三个条件。 &&
此处不能使用,因为结果未向量化。
您可以在下面的示例中看到这一点,其中生成的栅格很明显没有评估所有三个参数。第一条线索是,即使在第三个栅格中某些值是 NA,它也会产生结果。
我想我可以通过首先检查 x 和 y 的条件然后用这个结果分别用不同的函数检查 z 的条件来得到我想要的结果,但我希望能够做到这一切在一个函数中(至少看起来这应该是可能的)。
希望有人能指出我正确的方向。
library(raster)
fn <- system.file("external/test.grd", package="raster")
s <- stack(fn, fn,fn)
#Create grids
s[[1]] <- round(runif(ncell(s), 1, 2))
s[[2]] <- round(runif(ncell(s), 1, 2))
s[[3]] <- round(runif(ncell(s), 1, 2))
#convert some values in s[[3]] to NA
s[[3]][s[[3]] == 1]<- NA
#run overlay function
result.rast <- overlay(s[[1]], s[[2]], s[[3]], fun =
function(x,y,z) {
ifelse( x == 2 & y == 1 & z ==2, 1, 0)
} )
你试过了吗stackApply
?
您还可以将栅格堆栈的每一层用作矢量。 这是一个示例(不过,这可能是引用 rasterStack 中的单元格的更好方法)
tt <- raster(ncol=4,nrow=5)
tt[] <- 1
tts <- stack(tt,tt,tt)
tts[[1]][4,2]<-NA
# now the condition
tt2 <- (tts[[1]] == 1 & tts[[2]] == 1 & tts[[3]] == 1)
plot(tt2)
我没有看到没有使用第三个条件的证据。 NA 值是一个特例。请参阅函数 f2
了解您可以执行的一些操作。
使用较小的栅格更容易看到发生了什么
library(raster)
set.seed(0)
r <- raster(ncol=10, nrow=10, xmn=0, xmx=10, ymn=0, ymx=10)
r1 <- setValues(r, round(runif(ncell(r), 1, 2)))
r2 <- setValues(r, round(runif(ncell(r), 1, 2)))
r3 <- setValues(r, round(runif(ncell(r), 1, 2)))
r3[r3 == 1] <- NA
s <- stack(r1, r2, r3)
res1 <- overlay(s, fun =
function(x,y,z) {
ifelse( x == 2 & y == 1 & z ==2, 1, 0)
} )
#A more complex function, that keeps NAs
f2 <- function(x,y,z) {
a <- rep(0, length(x))
a[x == 2 & y == 1 & z ==2] <- 1
a[is.na(x) | is.na(y) | is.na(z)] <- NA
a
}
res2 <- overlay(s, fun = f2)