背景 - >我正在尝试使用覆盖功能删除某些森林类型中的所有旧林。如果森林是类型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)
答案 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)