Вот некоторые примеры данных
library(raster)
dem <- raster(ncol=8, nrow=7, xmn=720145, xmx=721993, ymn=5158211, ymx=5159835, crs='+proj=utm +zone=32 +datum=WGS84')
values(dem) <- ncell(dem):1
snow <- setValues(dem, c(1, 1, rep(1:3, each=18)))
snow[,c(2,5)] <- NA
snow[3] <- 3
plot(snow)
lines(as(dem, 'SpatialPolygons'))
text(dem)
На графике показаны классы снега (1, 2, 3) со значениями высоты над уровнем моря.
Мы можем использовать маску, но нужно разобраться с пропущенными значениями.
msnow <- reclassify(snow, cbind(NA, 0))
# mask to get only the snow elevations
x <- mask(dem, msnow, maskvalue=1, inverse=TRUE)
# minimum elevation of the snow-covered cells
minsnow <- minValue(x)
minsnow
#[1] 37
# snow elevation = 1
snowy <- reclassify(dem, rbind(c(-Inf, minsnow, NA), c(minsnow, Inf, 1)))
newsnow <- cover(snow, snowy)
s <- stack(dem, snow, newsnow)
names(s) <- c("elevation", "old_snow", "new_snow")
Вы были очень близки, как вы можете
r <- overlay(dem, snow, fun=function(e, s){ s[e >= minsnow] <- 1; s})
Но учтите, что это также перезаписывает высокие ячейки без снега.
Что можно исправить следующим образом:
r <- overlay(dem, snow, fun=function(e, s){ s[e >= minsnow & is.na(s)] <- 1; s})
Чтобы выбрать слои с более чем x% ячеек со значением 3 (здесь я использую порог 34%):
threshold = .34
s <- stack(snow, snow+1, snow+2)
f <- freq(snow)
f
# value count
#[1,] 1 14
#[2,] 2 13
#[3,] 3 15
#[4,] NA 14
nas <- f[is.na(f[,1]), 2]
ss <- subs(s, data.frame(from=3, to=1, subsWithNA=TRUE))
cs <- cellStats(ss, sum)
csf <- cs / (ncell(snow) - nas)
csf
# layer.1 layer.2 layer.3
#0.3571429 0.3095238 0.3333333
i <- which(csf < threshold)
use <- s[[i]]
#use
class : RasterStack
dimensions : 7, 8, 56, 2 (nrow, ncol, ncell, nlayers)
resolution : 231, 232 (x, y)
extent : 720145, 721993, 5158211, 5159835 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=utm +zone=32 +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
names : layer.2, layer.3
min values : 2, 3
max values : 4, 5