使用for循环和ifelse进行栅格覆盖的错误消息不一致

时间:2018-03-21 02:49:36

标签: r for-loop if-statement overlay raster

背景 - >我正在尝试使用覆盖功能删除某些森林类型中的所有旧林。如果森林是类型1并且年龄是> 250,然后我希望该单元格为0,如果它是类型2并且> 200我希望它为0,否则它可能是它。

问题 - >我得到两个不同的错误消息,没有出现一致性,代码产生了正确的结果(一次)。错误是:

#First error message
Error in setValues(x, value) : values must be a vector
Error in .local(x, i, j, ..., value) : cannot replace values on this raster (it is too large

#Second error message
Error in (function (x, fun, filename = "", recycle = TRUE, forcefun = FALSE, : cannot use this formula, probably because it is not vectorized

我想知道为什么它会更改错误消息(为什么它不一致),当然,我可以做些什么来修复我的代码以使其有效?

代码在没有for循环的情况下应用时也有效,并且也有,但我无法再次重现工作结果。

我的示例数据和代码:

library(raster)
library(dplyr)
set.seed(123)


r1 <- raster(ncol=100,nrow=100)
r2 <- raster(ncol=100,nrow=100)
r3 <- raster(ncol=100,nrow=100)
r4 <- raster(ncol=100,nrow=100)
r5 <- raster(ncol=100,nrow=100)

r1[] <- round(runif(n=ncell(r1), min=0, max = 1000))
r2[] <- round(runif(n=ncell(r1), min=0, max = 1000))
r3[] <- round(runif(n=ncell(r1), min=0, max = 1000))
r4[] <- round(runif(n=ncell(r1), min=0, max = 1000))
r5[] <- round(runif(n=ncell(r1), min=0, max = 1000))

testStack <- stack(x=c(r1,r2,r3,r4,r5))

testAge  <- raster(ncol=100,nrow=100)
testAge[]  <- round(runif(n=ncell(testAge), min=0,max=400))

testBec  <- raster(ncol=100,nrow=100)
testBec[]  <- round(runif(n=ncell(testBec), min = 1, max = 5))



testList <- list() # create a list to hold the files that will go into the raster stack

# create a for loop to run through raster stack and fill a list with the output rasters
for(i in 1:(nlayers(testStack))){
  testList[[i]] <- overlay(x=testStack, y=testBec, z=testAge, fun=function(x,y,z){ 
    ifelse(y == 1 & z > 249,    # if x is type 1 and z(age from inventory)
           0,                   # is >= 250, then y = 0, else      
           ifelse(y == 2 & z > 200,   # if x is type 2 and z is >200
                  0, x))        # y = 0, else keep x
    return(testList[[i]])       # return a list with rasters
  })
  testList[[i]] <- stack(testList[[i]])   
}

我正在使用Mac OS和RStudio版本1.1.383,R 3.4.2(2017-09-28)

2 个答案:

答案 0 :(得分:1)

示例数据

library(raster)
set.seed(123)
b <- brick(ncol=10,nrow=10, nl=5)
b <- setValues(b, round(runif(n=ncell(b)*nlayers(b), min=0, max = 1000)))
testAge  <- setValues(raster(b), round(runif(n=ncell(b), min=0,max=400)))
testBec  <- setValues(raster(b), round(runif(n=ncell(b), min = 1, max = 5)))

A&#34;栅格代数&#34;方法

test <- (testBec == 1 & testAge > 249) | (testBec == 2 & testAge > 200)
# values that test TRUE become 0, the others stay the same
r <- b * !test

或使用overlay获得相同的结果

f <- function(x, y, z) {
    i <- (y == 1 & z > 249) | (y == 2 & z > 200)
    x[i] <- 0
    x
}

rr <- overlay(b, testBec, testAge, fun=f)

答案 1 :(得分:0)

使用for循环执行此操作:

testList <- list() # create a list to hold the files that will go into the raster stack

# create a for loop to run through raster stack and fill a list with the output rasters
for(i in 1:(nlayers(testStack))){
  testList <- overlay(x=testStack[[i]], y=testBec, z=testAge, fun=function(x,y,z){ 

      temp <- ifelse(y == 1 & z > 249,0,       
                    ifelse(y == 2 & z > 200,0, x)) 
 return(temp)
})
  tList[[i]] <- stack(testList)   
}
second_stack <- stack(tList)