我试图在NDVI /降水的栅格堆栈上逐个像素地从回归运行中提取残差。当我用一小部分数据运行它时,我的脚本工作。但是,当我尝试运行我的整个研究区域时,我得到:“setValues(out,x)中的错误:值必须是数字,整数,逻辑或因子”
lm有效,因为我可以提取斜率和截距。我只是无法提取残差。
知道如何解决这个问题吗?
这是我的剧本:
setwd("F:/working folder/test")
gimms <- list.files(pattern="*ndvi.tif")
ndvi <- stack(gimms)
precip <- list.files(pattern="*pre.tif")
pre <- stack(precip)
s <- stack(ndvi,pre)
residualfun = function(x) { if (is.na(x[1])){ NA } else { m <- lm(x[1:6] ~ x[7:12], na.action=na.exclude)
r <- residuals.lm(m)
return (r)}}
res <- calc(s,residualfun)
答案 0 :(得分:1)
您的函数仅测试第一层是否显示NA
值以避免拟合模型。但其他层可能有NA
。您知道这是因为您在na.action = na.exclude
适合中添加了lm
问题是如果模型由于NA
而删除了某些值,则残差将仅具有非NA值的长度。这意味着,生成的r
向量将具有不同的长度,具体取决于图层中NA
值的数量。然后,calc
无法将堆栈中不同长度的结果与定义数量的层组合在一起
为避免这种情况,您需要在函数中指定r
的长度,并将属性残差指定为非NA值。
我建议使用以下函数,该函数现在适用于您提供的数据集。我添加了(1)如果你想扩展你的探索(nlayers
),可以比较每个层的更多层的可能性,(2)如果每层只有两个要比较的值(完美模型),则避免拟合模型,(3)如果模型可以适合的任何原因添加了try
,这将输出-1e32
的值,以便进一步测试。
library(raster)
setwd("/mnt/Data/Stackoverflow/test")
gimms <- list.files(pattern="*ndvi.tif")
ndvi <- stack(gimms)
precip <- list.files(pattern="*pre.tif")
pre <- stack(precip)
s <- stack(ndvi,pre)
# Number of layers of each
nlayers <- 6
residualfun <- function(x) {
r <- rep(NA, nlayers)
obs <- x[1:nlayers]
cov <- x[nlayers + 1:nlayers]
# Remove NA values before model
x.nona <- which(!is.na(obs) & !is.na(cov))
# If more than 2 points proceed to lm
if (length(x.nona) > 2) {
m <- NA
try(m <- lm(obs[x.nona] ~ cov[x.nona]))
# If model worked, calculate residuals
if (is(m)[1] == "lm") {
r[x.nona] <- residuals.lm(m)
} else {
# alternate value to find where model did not work
r[x.nona] <- -1e32
}
}
return(r)
}
res <- calc(s, residualfun)