我有2500个栅格数据,每个栅格可以包含1或2或3层。问题是需要为每个栅格选择最佳图层(该图层包含最小的NA值),我想为此目的使用R。示例数据(包含4个光栅文件)已上载here: 在第一步中,我想从仅包含3个图层的栅格文件中选择最佳图层。 我使用此代码:
list_files <- list.files(pattern = ".tif")
file_name <- paste0("best_layer" , list_files)
library(raster)
for(i in 1:length(list_files)){
r <- stack(list_files[i])
len <- nlayers(r)
if(len!=3)
next
r_1 <- sum(is.na(as.matrix(r[[1]])))
r_2 <- sum(is.na(as.matrix(r[[2]])))
r_3 <- sum(is.na(as.matrix(r[[3]])))
ifelse((r_1 < r_2 & r_1 < r_3),print("layer1"),
ifelse((r_2 < r_1 & r_2 < r_3)
,print("layer_2")
,print("layer_3")))
}
结果是:
[1] "layer_1"
[1] "layer_1"
[1] "layer_2"
[1] "layer_2"
但是当我将ifelse更改为编写最佳栅格图层时,就像这样的代码:
for(i in 1:length(list_files)){
r <- stack(list_files[i])
len <- nlayers(r)
if(len!=3)
next
r_1 <- sum(is.na(as.matrix(r[[1]])))
r_2 <- sum(is.na(as.matrix(r[[2]])))
r_3 <- sum(is.na(as.matrix(r[[3]])))
ifelse((r_1 < r_2 & r_1 < r_3),writeRaster(x = r[[1]], filename = file_name[i], format = 'GTiff'),
ifelse((r_2 < r_1 & r_2 < r_3)
,writeRaster(x = r[[2]], filename = file_name[i], format = 'GTiff')
,writeRaster(x = r[[3]], filename = file_name[i], format = 'GTiff')))
}
我希望R创建具有最佳图层的4个tiff文件,但是R仅创建第一个文件,并给了我这个错误:
Error in rep(yes, length.out = len) :
attempt to replicate an object of type 'S4'
如何解决此错误??? 谢谢。
答案 0 :(得分:0)
我认为问题可能在于您使用的是向量化函数(ifelse
),实际上您需要普通的旧if ... else
。或者,更好的做法是i <- which.min(c(r_1, r_2, r_3))
,而您根本不需要if
:
rv <- sapply(r, function(rj) sum(is.na(as.matrix(rj))))
ind <- which.min(rv)
writeRaster(x = r[[ind]], filename = file_name[i], format = 'GTiff')
说明:在1..3中运行j的命令后,sapply
返回三个数字rv
的向量。然后,which.min
返回该向量中最小值的位置。要使代码更加明确,请执行以下操作:
count.nas <- function(rj) sum(is.na(as.matrix(rj)))
rv <- sapply(r, count.nas)
ind <- which.min(rv)
writeRaster(x = r[[ind]], filename = file_name[i], format = 'GTiff')
由于我没有minimal reproducible example,因此我没有检查此代码。
答案 1 :(得分:0)
我认为,这是一种更好地了解自己所追求的方式
示例数据
library(raster)
f <- system.file("external/rlogo.grd", package="raster")
b <- brick(f)
b[[1]][1:12] <- NA
b[[2]][5:10] <- NA
b[[3]][1:10] <- NA
查找最佳图层的功能
fun <- function(x){
if (nlayers(x) > 1) {
cnt <- freq(x, value=NA)
which.min(cnt)
} else {
-1
}
}
使用功能
fun(b)
然后可能是这样的:
for (i in 1:length(list_files)) {
b <- brick(list_files[i])
j <- fun(b)
if (j > 0) {
writeRaster(b[[j]], file_name[i])
}
}