从逐像素回归中提取残差

时间:2017-10-17 08:46:07

标签: r raster lm

我试图在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)

这是我的数据:https://1drv.ms/u/s!AhwCgWqhyyDclJRjhh6GtentxFOKwQ

1 个答案:

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

Residuals by layer