在栅格中将NA设置为零,其他栅格在该单元格中具有值

时间:2018-01-18 23:57:30

标签: r arcgis raster

我有11个大光栅文件,包含大约314578920个单元格。这些细胞中的一些含有NA。如果其他栅格在该特定单元格中具有值,我想将NA替换为零。但是在所有栅格中包含NA的细胞应该是相同的。例如,请参见下图:

enter image description here

我创建了五个栅格(顶行)来说明我的问题(但实际上我有11个栅格)。输出栅格应该像底行栅格一样。

将所有NA替换为零(即使用r[is.na(r[])] <- 0)会使光栅变得太大而内存无法处理。或者,省略NA并不符合我的目的。任何关于如何解决这个问题的想法都将受到高度赞赏 示例代码:

library(raster)
r <- raster(nrow=5, ncol=5) # create empty raster
r[] <- rnorm(length(r))     # assign random values to each cell
r[1:5] <- NA                # assign first row with NA

2 个答案:

答案 0 :(得分:1)

示例数据:

library(raster)
r <- raster(nrow=5, ncol=5, vals=1:25)
set.seed(20181801)
s <- stack(lapply(1:5, function(i) {r[sample(25, 15)] <- NA; r}))

跨层计算NA个值

i <- sum(is.na(s))

重新分类使得所有单元格值都变为零,除非所有图层都具有NA

nl <- nlayers(s)
j <- reclassify(i, rbind(c(0, nl-1, 0), c(nl, nl ,NA)), right=NA)

使用cover在至少有一个值为

的单元格中将NA值替换为零
z <- cover(s, j)

使用calc的替代方法:

编写一个能够为矢量或矩阵执行所需操作的函数:

f <- function(x) {
    i <- sum(is.na(x))
    if (i > 0 & i < 5) {
        x[is.na(x)] <- 0
    }
    x
}

zz <- calc(s, f)

将这些功能用于更直接的R语言的一个重要原因是它们都是内存安全的。

顺便提一下,你提到r[is.na(r[])] <- 0由于内存限制而无效。通过执行is.na(r[]),您可以创建所有值的向量,从而要求发生该问题。您可以尝试r[is.na(r)] <- 0

答案 1 :(得分:0)

这是一个快速入侵,可以替换所有提供的栅格中不是NA的{​​{1}}值。所有提供的栅格中NA的任何单元格都将保留NA。 (我假设,顺便说一句,所有栅格都是相同的尺寸......)

我会制作一些更简单的数据。我选择将它们存储在一个列表中,因为这使得这个解决方案更容易阅读(我认为),但也更容易扩展到你需要的更多栅格。

NA

我将在这个数据中创建两种类型的set.seed(2) rs <- lapply(1:2, function(ign) { r <- raster(nrow=3, ncol=3) r[] <- sample(length(r)) r }) :一个在(和应该被忽略)中,一个只在一个中(并且应该替换为0):

NA

内部的Rasters(您可能知道)只是rs[[1]][1:2] <- NA rs[[2]][2] <- NA lapply(rs, head) # [[1]] # 1 2 3 # 1 NA NA 5 # 2 9 7 4 # 3 1 8 3 # [[2]] # 1 2 3 # 1 5 NA 2 # 2 8 1 7 # 3 3 4 6 个向量,因此我将映射每个索引为numeric

NA

知道了,我们可以找到所有人共有的指数。可能有比这更容易的东西,但它有效(并且可读):

nas <- lapply(rs, function(r) which(is.na(r[])))
nas
# [[1]]
# [1] 1 2
# [[2]]
# [1] 2

现在我们只删除所有索引:

na_in_all <- Reduce(intersect, nas)
na_in_all
# [1] 2

现在我们重新迭代栅格和要替换的索引列表:

nas <- lapply(nas, setdiff, na_in_all)
nas
# [[1]]
# [1] 1
# [[2]]
# integer(0)

这并不一定能解决稀疏矩阵增长过大的问题,但这几乎肯定比你问题中的全局替换 - rs <- mapply(function(r,i) { if (length(i)) r[i] <- 0 r }, rs, nas) head(rs[[1]]) # 1 2 3 # 1 0 NA 5 # 2 9 7 4 # 3 1 8 3 head(rs[[2]]) # 1 2 3 # 1 5 NA 2 # 2 8 1 7 # 3 3 4 6 更好。