繁体   English   中英

从栅格堆栈中删除具有许多NA的栅格图层

[英]Remove raster layers with many NAs from rasterstack

我有一个具有数千层的RasterStack 但是,某些层有很多NA,因此我将通过设置阈值来排除这些层。 我使用for循环正确地做到了,但这很慢。 我试图用calc来做,但是我的函数失败了。 这是我的尝试,为了使处理速度更快,我希望您能提出一些建议。

library(raster)
lst<-stack(r1,r2,r3,r4) # 
lst_new<-stack()
for (i in 1: nlayers(lst)){
   # total number of cells without NA
   no_NA<-length(lst[[i]][!is.na(lst[[i]])]) #
   if(no_NA >= 14652){ # 97% 
     l<-lst[[i]]
     lst_new<-stack(lst_new,l)
     }
   }
  #This code works OK but slow for big rasterstack. So I tried the
  # following using calc function    
  remove.badL<-function(x){
          no_NA<-length(x[is.na(x)])
          if(no_NA >= 14652){
          return(x)
          }
         }
  lst_new<-calc(lst,fun=remove.badL) 
# this is the error I got 

错误(函数(类,fdef,mtable):无法为签名“ RasterBrick”,“ NULL””的函数“ writeValues”找到继承的方法

我将不胜感激任何建议。 谢谢

这是使用is.nacellStats和条件RasterStack子集的一种方法。

首先,让我们创建一些示例数据:

library(raster)
s <- stack(replicate(10, raster(matrix(runif(1e6), 1e3))))
s[s > 0.95] <- NA # insert some NAs

我们可以使用以下命令返回每层NA单元的数量:

cellStats(is.na(s), sum)

有了这些知识,我们就可以在子集操作中使用这些计数:

thr <- 14652
s2 <- s[[which(cellStats(is.na(s), sum) < thr)]]

具有小于层thr (这里,14652) NA细胞将被保留在新的堆栈, s2 ,而那些具有更NA旨意被抛弃。


将所有这些应用于数据,您应该能够使用:

lst_new <- lst[[cellStats(is.na(lst), sum) < 14652]]

处理庞大的数据集时, cellStats可能并不总是最佳选择。 例如,将@jbaums样本数据扩展到n = 100层,这在我的计算机上花费了相当长的时间。

## sample data, n = 100
library(raster)

set.seed(10)
s <- stack(replicate(100, raster(matrix(runif(1e6), 1e3))))
s[s > 0.95] <- NA

## set na limit (e.g., 5% of all cells)
limit <- 0.05 * ncell(s)


### cellStats -----

system.time(
  id1 <- cellStats(is.na(s), sum) < limit
)
# user  system elapsed 
# 28.794   0.253  29.050

代替使用cellStats ,您可以例如使用并行化的foreach创建手动指示少量丢失数据的索引向量。

### parallel version -----

## open parallel backend
library(doParallel)
cl <- makeCluster(detectCores() - 1)
registerDoParallel(cl)

## loop over layers in parallel
system.time(
  id2 <- foreach(i = unstack(s), .packages = "raster", 
                 .combine = "c") %dopar% {
                   sum(is.na(i[])) < limit
                 }
)
# user  system elapsed 
# 0.337   0.005   3.802 

如您所见,后一种方法的执行速度相当快,并且同时返回相同的结果。

## similarity check
identical(as.logical(id1), id2)
[1] TRUE

剩下要做的唯一一件事就是关闭并行后端

## deregister parallel backend
stopCluster(cl)

和创建的子集s基于所导出的指标向量。

## data subset
s[[which(id2)]]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM