首页 > 解决方案 > 删除R中每个像素的时间序列栅格中的异常值

问题描述

基本上,我在堆栈中有一个时间序列的栅格。这是我的工作流程:

将堆栈转换为数据框,使每一行代表一个像素,每一列代表一个数据。这个过程相当简单,所以这里没有问题。

对于每一行(像素),识别异常值并将其设置为 NA。所以在这种情况下,我想设置异常值是什么。例如,假设我想将所有大于第 75 个百分位的值设置为 NA。目标是当我计算平均值时,异常值不会影响计算。在这种情况下,异常值要高几个数量级,因此它们会显着影响平均值。

我在网上得到了一些帮助,并想出了这个代码:

my_data %>%
  rowwise() %>%
  mutate(across(is.numeric, ~ if (. > as.numeric(quantile(across(), .75, na.rm=TRUE))) NA else .))

问题是,由于它是一个栅格,因此在某些行中有很多 NA 值,我需要在计算评估单元格时忽略分位数函数(见下文)

样本

使用na.rm=TRUE似乎是解决方案,但现在我遇到了一个新错误

错误:mutate()输入有问题..1。我..1 = across(...)。x 需要 TRUE/FALSE 的缺失值 i 错误发生在第 1 行。

我知道要解决这个问题,如果它是 NA,我需要告诉 if 函数忽略该值,但是 dplyr 语法对我来说非常复杂,所以我需要一些关于如何做到这一点的帮助。

期待学习更多,如果有更好的方法来做我想做的事。我认为我没有很好地解释它,但希望代码有所帮助。

标签: rdplyrtime-seriesrasteroutliers

解决方案


当问一个 R 问题时,你应该总是包含一些示例数据。使用代码创建数据(见下文)或使用 R 附带的文件(如果可以避免,请不要使用)。dput请参阅 R 附带的帮助文件或此站点上的其他问题以获取示例和灵感。

示例数据:

library(terra)
r <- rast(ncols=10, nrows=10, nlyr=10)
set.seed(1)
v <- runif(size(r))
v[sample(size(r), 100)] <- NA
values(r) <- v

解决方案:

首先编写一个函数来执行您想要的操作,并使用向量

f <- function(x) {
    q <- quantile(x, .75, na.rm=TRUE)
    x[x>q] <- NA
    x
}

现在将其应用于栅格数据

x <- app(r, f)

有了raster包裹,它会像

library(raster)
rr <- brick(r)
xx <- calc(rr, f)

请注意,您不应该创建 data.frame,但如果您这样做了,您可以执行类似的操作dd <- t(apply(d, 1, f))


推荐阅读