如何解决此错误“ rep(yes,length.out = len)中的错误:尝试复制'S4'类型的对象”

时间:2019-07-23 10:19:49

标签: r r-raster rgdal

我有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'

如何解决此错误??? 谢谢。

2 个答案:

答案 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])
   }
}