R: Annual composite raster based on median: 如何获取每个像素的原始图层的索引?
R: Annual composite raster based on the median: How to get the index of the original layer for each pixel?
我有一个 rasterstacks 列表,它们是不同波段的时间序列(300+ 层)。时间序列是不规则的,因此我想根据中值 ndvi 创建年度复合材料。因此,从一年的可用图像中,选择具有(接近)中值 ndvi 的像素。对于其他波段,我想基于此 ndvi 合成材料创建年度合成材料。我尝试制作一个掩码,其中每个像素都具有用于中值 ndvi 合成的图像索引值。我将把它应用到其他波段,所以我每年每个波段都有 'the same' 年度综合。
不幸的是,我一直在做面具。我创建了一些虚拟数据,并以某种方式 returns 两个索引栅格(一个值为 1-3,另一个为 2-4),而我期望有一个(值为 1-4)。
此外,我的函数无法处理 NA 值,将 na.rm 添加到 calc 函数也无法解决此问题。
我想知道我需要调整什么以获得一个值为 1-4 的输出层,以及如何让 'which'-函数处理 NA。
#dummy data:
r <- raster(nrow=5, ncol=5)
set.seed(20181114)
s <- stack(lapply(1:5, function(i) setValues(r, runif(25, max=50))))
names(s) <- c("X2001", "X2002a", "X2002b", "X2002c", "X2002d")
#s$X2002a[2] <- NA
AnnualMask <- function(ts, year){
year <- as.character(year)
ts_year <- subset(ts, (grep(year, names(ts))))
indexraster <- calc(ts_year, function(x){
medianval <- median(x, na.rm = TRUE)
which(abs(x - medianval) == min(abs(x - medianval)))
})
return(indexraster)
}
mask2002 <- AnnualMask(s, 2002)
plot(mask2002)
我还不确定值在 1-4 之间的部分,但是这里有一些关于 which
部分和处理 NA
:
# here is some dummy data
x <- c(3,4,5,NA,1,-2-45,2,54)
# now here is the which part as found in your function
medianval <- median(x, na.rm = TRUE)
which(abs(x - medianval) == min(abs(x - medianval)))
# returning in this case
integer(0)
# now let's add na.rm = T in the min function
medianval <- median(x, na.rm = TRUE)
which(abs(x - medianval) == min(abs(x - medianval), na.rm = T))
# returning
[1] 1
感谢您提供很好的示例数据:
library(raster)
r <- raster(nrow=5, ncol=5)
set.seed(20181114)
s <- stack(lapply(1:5, function(i) setValues(r, runif(25, max=50))))
names(s) <- c("X2001", "X2002a", "X2002b", "X2002c", "X2002d")
s[[2]][1:3] <- NA
这里有两个功能相同。 #1 可能更简单,但效率可能较低。
annualIndex1 <- function(ts, year) {
year <- as.character(year)
ts_year <- subset(ts, (grep(year, names(ts))))
medianval <- calc(ts_year, median, na.rm = TRUE)
dif <- abs(ts_year - medianval)
which.min(dif)
}
x1 <- annualIndex1(s, 2002)
这个使用 calc
组合多个步骤
annualIndex2 <- function(ts, year){
year <- as.character(year)
ts_year <- subset(ts, (grep(year, names(ts))))
fun <- function(x){
y <- median(x, na.rm=TRUE)
which.min(abs(x - y))
}
calc(ts_year, fun)
}
x2 <- annualIndex2(s, 2002)
结果是一样的(而且没有NA)
all(values(x1) == values(x2))
#[1] TRUE
但是,如果您在所有层中都设置一个单元格 NA
s[5] <- NA
功能 2 失败。可以这样调整
annualIndex2b <- function(ts, year){
year <- as.character(year)
ts_year <- subset(ts, (grep(year, names(ts))))
fun <- function(x){
if (all(is.na(x))) return( NA )
y <- median(x, na.rm=TRUE)
which.min(abs(x - y))
}
calc(ts_year, fun)
}
x2b <- annualIndex2b(s, 2002)
您使用了术语 "mask",但实际上您是在创建索引,您可以像这样在 strackSelect
中使用适当的单元格吗:
ts_year <- subset(ts, (grep(year, names(ts))))
v <- stackSelect(ts_year, x2)
我有一个 rasterstacks 列表,它们是不同波段的时间序列(300+ 层)。时间序列是不规则的,因此我想根据中值 ndvi 创建年度复合材料。因此,从一年的可用图像中,选择具有(接近)中值 ndvi 的像素。对于其他波段,我想基于此 ndvi 合成材料创建年度合成材料。我尝试制作一个掩码,其中每个像素都具有用于中值 ndvi 合成的图像索引值。我将把它应用到其他波段,所以我每年每个波段都有 'the same' 年度综合。
不幸的是,我一直在做面具。我创建了一些虚拟数据,并以某种方式 returns 两个索引栅格(一个值为 1-3,另一个为 2-4),而我期望有一个(值为 1-4)。 此外,我的函数无法处理 NA 值,将 na.rm 添加到 calc 函数也无法解决此问题。 我想知道我需要调整什么以获得一个值为 1-4 的输出层,以及如何让 'which'-函数处理 NA。
#dummy data:
r <- raster(nrow=5, ncol=5)
set.seed(20181114)
s <- stack(lapply(1:5, function(i) setValues(r, runif(25, max=50))))
names(s) <- c("X2001", "X2002a", "X2002b", "X2002c", "X2002d")
#s$X2002a[2] <- NA
AnnualMask <- function(ts, year){
year <- as.character(year)
ts_year <- subset(ts, (grep(year, names(ts))))
indexraster <- calc(ts_year, function(x){
medianval <- median(x, na.rm = TRUE)
which(abs(x - medianval) == min(abs(x - medianval)))
})
return(indexraster)
}
mask2002 <- AnnualMask(s, 2002)
plot(mask2002)
我还不确定值在 1-4 之间的部分,但是这里有一些关于 which
部分和处理 NA
:
# here is some dummy data
x <- c(3,4,5,NA,1,-2-45,2,54)
# now here is the which part as found in your function
medianval <- median(x, na.rm = TRUE)
which(abs(x - medianval) == min(abs(x - medianval)))
# returning in this case
integer(0)
# now let's add na.rm = T in the min function
medianval <- median(x, na.rm = TRUE)
which(abs(x - medianval) == min(abs(x - medianval), na.rm = T))
# returning
[1] 1
感谢您提供很好的示例数据:
library(raster)
r <- raster(nrow=5, ncol=5)
set.seed(20181114)
s <- stack(lapply(1:5, function(i) setValues(r, runif(25, max=50))))
names(s) <- c("X2001", "X2002a", "X2002b", "X2002c", "X2002d")
s[[2]][1:3] <- NA
这里有两个功能相同。 #1 可能更简单,但效率可能较低。
annualIndex1 <- function(ts, year) {
year <- as.character(year)
ts_year <- subset(ts, (grep(year, names(ts))))
medianval <- calc(ts_year, median, na.rm = TRUE)
dif <- abs(ts_year - medianval)
which.min(dif)
}
x1 <- annualIndex1(s, 2002)
这个使用 calc
组合多个步骤
annualIndex2 <- function(ts, year){
year <- as.character(year)
ts_year <- subset(ts, (grep(year, names(ts))))
fun <- function(x){
y <- median(x, na.rm=TRUE)
which.min(abs(x - y))
}
calc(ts_year, fun)
}
x2 <- annualIndex2(s, 2002)
结果是一样的(而且没有NA)
all(values(x1) == values(x2))
#[1] TRUE
但是,如果您在所有层中都设置一个单元格 NA
s[5] <- NA
功能 2 失败。可以这样调整
annualIndex2b <- function(ts, year){
year <- as.character(year)
ts_year <- subset(ts, (grep(year, names(ts))))
fun <- function(x){
if (all(is.na(x))) return( NA )
y <- median(x, na.rm=TRUE)
which.min(abs(x - y))
}
calc(ts_year, fun)
}
x2b <- annualIndex2b(s, 2002)
您使用了术语 "mask",但实际上您是在创建索引,您可以像这样在 strackSelect
中使用适当的单元格吗:
ts_year <- subset(ts, (grep(year, names(ts))))
v <- stackSelect(ts_year, x2)