基于每个团块上网格单元数差异的子集 R rasterstacks
Subset R rasterstacks based on difference in grid cell number on each clumps
我想创建栅格堆栈的子集,并将它们写为新的堆栈,当上一层和下一层之间的差异在每个栅格层块之后都是 NA 时。如果没有团块,我将通过遵循罗伯特在 中的回答(如下面的脚本)来实现这一点。但是,我也想 运行 通过考虑团块来做到这一点。每层可能有 1 或 2 个团块。因此,从下面示例数据堆栈中的 layer 1
开始,我想确定团块编号,并为每个团块创建一个栅格堆栈子集,直到上一层和下一层之间没有重叠像素(即,两层之间的差异都是NA
)。所以我想要的是;从layer 1
开始,对于每个clump,保留所有在上一层和下一层之间至少有一个公共像素的层,将它们写成1个stack,然后移动到下一层。
在示例 r_stk
中,我想为 clump 1(顶部)保留层 1:8,将它们分配为 1 个堆栈,运行 为 clump 2(底部),并再次保留层 1:5 将它们分配为新堆栈,依此类推。
下面是示例数据和代码,如果没有团块,可以在 之后正常工作。
library(raster)
library(tidyverse)
#Create null raster, fill values and get stack with clumps
r<-raster(extent(-180,-140,34,83),
crs="+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0",
resolution=10, vals=NULL)
r
#Make series of raters with clumps and stack
r1<-r
values(r1)<-c(70,69,NA,NA,73,70,NA,NA,NA,NA,NA,NA,100,99,NaN,NA,101,99,76,NA)
r2<-r
values(r2)<-c(89,81,72,NA,87,77,69,NA,NA,NA,NA,NA,89,99,NaN,NA,89,100,84,NA)
r3<-r
values(r3)<-c(112,103,86,76,90,82,78,NaN,NA,NA,NA,NA,79,93,NaN,NA,78,93,88,NA)
r4<-r
values(r4)<-c(125,115,98,88,84,81,82,NaN,NA,NA,NA,NA,69,81,NaN,NA,69,80,83,NA)
r5<-r
values(r5)<-c(132,125,110,100,77,76,82,NaN,NA,NA,NA,NA,NaN,71,NaN,NA,70,71,74,NA)
r6<-r
values(r6)<-c(118,114,103,93,72,75,77,NaN,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA)
r7<-r
values(r7)<-c(98,92,76,69,70,70,76,NaN,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA)
r8<-r
values(r8)<-c(76,73,68,NA,76,73,NaN,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA)
r9<-r
values(r9)<-c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA)
r_stk<-stack(r1,r2,r3,r4,r5,r6,r7,r8,r9)
plot(r_stk) #raster stack with clumps
如果我移除较小的团块并且每层只保留一个团块,效果很好
我想 运行 为每一层上的每个团块做这个
我想,我正在尝试 运行 在脚本之上增加一个 for 循环
低于此考虑团块但无法成功 运行
singleclump_lst<-list()
for (i in 1: nlayers(r_stk)){
rasi<-subset(r_stk,i)
#Classify based on clumps
clumps<-clump(rasi,directions=8)
clumpFreq2 <- as.data.frame(freq(clumps))
clumpFreq_na2<-clumpFreq2%>%
drop_na()
clumpFreq_na2
excludeID_i <-clumpFreq_na2$value[which(clumpFreq_na2$count == max(clumpFreq_na2$count))]
excludeID_i
subNA_i <- function(a, b) {
a[!b %in% excludeID_i] <- NA
return(a)}
rasclmp_i<-overlay(rasi,clumps,fun=subNA_i)
singleclump_lst[[i]]<-rasclmp_i
}
rr_stk<-stack(singleclump_lst)
rr_stk
plot(rr_stk)
out <- lst <- list()
nc <- ncell(rr_stk)
for (i in 1:nlayers(rr_stk)) {
if (i==1) {
j <- 1
s <- rr_stk[[i]]
} else {
s <- s + rr_stk[[i]]
}
if (freq(s, value=NA) == nc) {
ii <- max(j, i-1)
out <- c(out, rr_stk[[j:ii]])
s <- rr_stk[[i]]
j <- i
}
}
out <- c(out, rr_stk[[j:i]])
out
您的示例数据
library(raster)
b <- brick(extent(-180,-140,34,83), nrow=5, ncol=4,
crs="+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0")
values(b) <- cbind(
c(70,69,NA,NA,73,70,NA,NA,NA,NA,NA,NA,100,99,NaN,NA,101,99,76,NA),
c(89,81,72,NA,87,77,69,NA,NA,NA,NA,NA,89,99,NaN,NA,89,100,84,NA),
c(112,103,86,76,90,82,78,NaN,NA,NA,NA,NA,79,93,NaN,NA,78,93,88,NA),
c(125,115,98,88,84,81,82,NaN,NA,NA,NA,NA,69,81,NaN,NA,69,80,83,NA),
c(132,125,110,100,77,76,82,NaN,NA,NA,NA,NA,NaN,71,NaN,NA,70,71,74,NA),
c(118,114,103,93,72,75,77,NaN,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA),
c(98,92,76,69,70,70,76,NaN,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA),
c(76,73,68,NA,76,73,NaN,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA),
c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA))
没有团块的解决方案(即,对于单个团块)如上一个答案,但包装到一个函数中
one_clump <- function(r_stk) {
out <- lst <- list()
nc <- ncell(r_stk)
for (i in 1:nlayers(r_stk)) {
if (i==1) {
j <- 1
s <- r_stk[[i]]
} else {
s <- s + r_stk[[i]]
}
if (freq(s, value=NA) == nc) {
ii <- max(j, i-1)
out <- c(out, r_stk[[j:ii]])
s <- r_stk[[i]]
j <- i
}
}
out <- c(out, r_stk[[j:i]])
out
}
获取团块及其唯一 ID
clm <- clump(b[[1]])
u <- unique(clm)
屏蔽单个簇数据的函数
f <- function(i) {
rr <- clm == i
bb <- mask(b, rr, maskvalue=0)
one_clump(bb)
}
为每个 ID 调用 f
x <- lapply(u, f)
x 是一个列表。每个元素都是一个团块的结果
length(x)
#2
丛#1 的列表
r1 <- x[[1]]
我想创建栅格堆栈的子集,并将它们写为新的堆栈,当上一层和下一层之间的差异在每个栅格层块之后都是 NA 时。如果没有团块,我将通过遵循罗伯特在 layer 1
开始,我想确定团块编号,并为每个团块创建一个栅格堆栈子集,直到上一层和下一层之间没有重叠像素(即,两层之间的差异都是NA
)。所以我想要的是;从layer 1
开始,对于每个clump,保留所有在上一层和下一层之间至少有一个公共像素的层,将它们写成1个stack,然后移动到下一层。
在示例 r_stk
中,我想为 clump 1(顶部)保留层 1:8,将它们分配为 1 个堆栈,运行 为 clump 2(底部),并再次保留层 1:5 将它们分配为新堆栈,依此类推。
下面是示例数据和代码,如果没有团块,可以在
library(raster)
library(tidyverse)
#Create null raster, fill values and get stack with clumps
r<-raster(extent(-180,-140,34,83),
crs="+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0",
resolution=10, vals=NULL)
r
#Make series of raters with clumps and stack
r1<-r
values(r1)<-c(70,69,NA,NA,73,70,NA,NA,NA,NA,NA,NA,100,99,NaN,NA,101,99,76,NA)
r2<-r
values(r2)<-c(89,81,72,NA,87,77,69,NA,NA,NA,NA,NA,89,99,NaN,NA,89,100,84,NA)
r3<-r
values(r3)<-c(112,103,86,76,90,82,78,NaN,NA,NA,NA,NA,79,93,NaN,NA,78,93,88,NA)
r4<-r
values(r4)<-c(125,115,98,88,84,81,82,NaN,NA,NA,NA,NA,69,81,NaN,NA,69,80,83,NA)
r5<-r
values(r5)<-c(132,125,110,100,77,76,82,NaN,NA,NA,NA,NA,NaN,71,NaN,NA,70,71,74,NA)
r6<-r
values(r6)<-c(118,114,103,93,72,75,77,NaN,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA)
r7<-r
values(r7)<-c(98,92,76,69,70,70,76,NaN,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA)
r8<-r
values(r8)<-c(76,73,68,NA,76,73,NaN,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA)
r9<-r
values(r9)<-c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA)
r_stk<-stack(r1,r2,r3,r4,r5,r6,r7,r8,r9)
plot(r_stk) #raster stack with clumps
如果我移除较小的团块并且每层只保留一个团块,效果很好 我想 运行 为每一层上的每个团块做这个 我想,我正在尝试 运行 在脚本之上增加一个 for 循环 低于此考虑团块但无法成功 运行
singleclump_lst<-list()
for (i in 1: nlayers(r_stk)){
rasi<-subset(r_stk,i)
#Classify based on clumps
clumps<-clump(rasi,directions=8)
clumpFreq2 <- as.data.frame(freq(clumps))
clumpFreq_na2<-clumpFreq2%>%
drop_na()
clumpFreq_na2
excludeID_i <-clumpFreq_na2$value[which(clumpFreq_na2$count == max(clumpFreq_na2$count))]
excludeID_i
subNA_i <- function(a, b) {
a[!b %in% excludeID_i] <- NA
return(a)}
rasclmp_i<-overlay(rasi,clumps,fun=subNA_i)
singleclump_lst[[i]]<-rasclmp_i
}
rr_stk<-stack(singleclump_lst)
rr_stk
plot(rr_stk)
out <- lst <- list()
nc <- ncell(rr_stk)
for (i in 1:nlayers(rr_stk)) {
if (i==1) {
j <- 1
s <- rr_stk[[i]]
} else {
s <- s + rr_stk[[i]]
}
if (freq(s, value=NA) == nc) {
ii <- max(j, i-1)
out <- c(out, rr_stk[[j:ii]])
s <- rr_stk[[i]]
j <- i
}
}
out <- c(out, rr_stk[[j:i]])
out
您的示例数据
library(raster)
b <- brick(extent(-180,-140,34,83), nrow=5, ncol=4,
crs="+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0")
values(b) <- cbind(
c(70,69,NA,NA,73,70,NA,NA,NA,NA,NA,NA,100,99,NaN,NA,101,99,76,NA),
c(89,81,72,NA,87,77,69,NA,NA,NA,NA,NA,89,99,NaN,NA,89,100,84,NA),
c(112,103,86,76,90,82,78,NaN,NA,NA,NA,NA,79,93,NaN,NA,78,93,88,NA),
c(125,115,98,88,84,81,82,NaN,NA,NA,NA,NA,69,81,NaN,NA,69,80,83,NA),
c(132,125,110,100,77,76,82,NaN,NA,NA,NA,NA,NaN,71,NaN,NA,70,71,74,NA),
c(118,114,103,93,72,75,77,NaN,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA),
c(98,92,76,69,70,70,76,NaN,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA),
c(76,73,68,NA,76,73,NaN,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA),
c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA))
没有团块的解决方案(即,对于单个团块)如上一个答案,但包装到一个函数中
one_clump <- function(r_stk) {
out <- lst <- list()
nc <- ncell(r_stk)
for (i in 1:nlayers(r_stk)) {
if (i==1) {
j <- 1
s <- r_stk[[i]]
} else {
s <- s + r_stk[[i]]
}
if (freq(s, value=NA) == nc) {
ii <- max(j, i-1)
out <- c(out, r_stk[[j:ii]])
s <- r_stk[[i]]
j <- i
}
}
out <- c(out, r_stk[[j:i]])
out
}
获取团块及其唯一 ID
clm <- clump(b[[1]])
u <- unique(clm)
屏蔽单个簇数据的函数
f <- function(i) {
rr <- clm == i
bb <- mask(b, rr, maskvalue=0)
one_clump(bb)
}
为每个 ID 调用 f
x <- lapply(u, f)
x 是一个列表。每个元素都是一个团块的结果
length(x)
#2
丛#1 的列表
r1 <- x[[1]]