繁体   English   中英

R在时间序列NA中的离群值已包含NA

[英]R set outliers in time series NA in series already containing NA

我有一个包含NA和一个突然跳跃的时间序列,如下所示:

input=c(1:5, NA, 6:7,0,9:12)

其中7,0,9被认为是一个跳转,对于该跳转,应将NA替换为0。

我想删除突然出现的第一个值(设置为跳变的设定值,在示例中,变化> 1)并将其设置为NA

该示例的输出应如下所示:

output=c(1:5,NA,6:7,NA,9:12)

我只想设置异常值NA,我不想覆盖其余值。 跳跃既可以是负的,也可以是正的。

我遇到的问题:

  1. 现有NA值后的值被计为跳跃
  2. 异常值之后的“跳回”被视为跳

两者都导致产生了不必要的NA,因此我尝试保留尽可能多的原始数据。

有任何想法吗? 我被困了一段时间。 提前致谢!

三种情况非常相似,但在例外方面需要不同程度的困难:

情况1

如果模式总是由于中断而跳回到1增量,则我将创建类似于完美矢量的vector_check input中与此不同的所有内容都应设置为NA

vector_check <- min(input):max(input)
inds         <- vector_check != input
input[inds]  <- NA

情况二

如果该模式难以预测,并且您基本上希望寻找“不规则”模式,则情况将会更加复杂。 一种可能的解决方案是创建一个while bump_inds ,该bump_inds检查哪些增量大于2(或任何看起来合理的值),然后用NA替换有问题的位置bump_inds 在这里,我假设一个异常值会产生两个较大的增量:一个是因为该值突然下降(增加),另一个是因为它又上升(下降又下降)到旧值。 继续进行此过程,直到没有问题的位置为止:

bump_ind <- rep(0, 3)

while(length(bump_ind) > 1){
  bump_ind        <- which( abs(diff(input)) > 2 )
  input[bump_ind[2]] <- NA
}

input
# [1]  1  2  3  4  5 NA  6  7 NA  9 10 11 12

情况3

根据您的真实数据sensor的第三种选择表明,数据不必跳回到上一级:

input    <- c(20.2,20.2,20.2,20.2,20.1,20.2,20.2,20.1,20.2, 20.2,20.2,20.2,17.7,
              18.9,19.3,19.4,19.4,19.4,19.5,19.5,19.5)
bump_ind <- rep(0, 3)

while(length(bump_ind) > 1){
  bump_ind        <- which( abs(diff(input)) > 2 )
  if(length(bump_ind) > 2){
    bump_ind <- bump_ind[1:2]
  }
  if( length(bump_ind) == 1 ){
      input[bump_ind[1] + 1] <- NA
  } else if( diff(bump_ind > 1) ){
      input[bump_ind[1] + 1] <- NA
  } else{
      input[bump_ind[2]] <- NA
  }
}

input
# [1] 20.2 20.2 20.2 20.2 20.1 20.2 20.2 20.1 20.2 20.2 20.2 20.2   NA 18.9 19.3
# [16] 19.4 19.4 19.4 19.5 19.5 19.5

这可能是一个更可靠的解决方案,因为如果需要,您可以在下面修改数据的线性模型:

您的数据:

 input <- c(1:5, NA, 6:7,0,9:12)

一系列数字:

x <- seq_len(length(input))

为线性模型的残差选择一些阈值:

threshhold = 2

计算数据和残差的线性模型,然后选择离群值:

select <- abs((predict(lm(input ~ x), newdata = data.frame(x = x)) -input)) >= threshhold

将异常值替换为“ NA”

input[select] <- NA
input
 [1]  1  2  3  4  5 NA  6  7 NA  9 10 11 12

编辑:与您的数据:

input=c(20.2, 20.2, 20.2, 20.2,
        20.1, 20.2, 20.2, 20.1,
        20.2, 20.2, 20.2, 20.2,
        17.7, 18.9, 19.3, 19.4,
        19.4, 19.4, 19.5, 19.5,
        19.5)

x <- seq_len(length(input))
threshhold = 0.7
select <- abs((predict(lm(input ~ x), newdata = data.frame(x = x)) - input)) >= threshhold

inputnew <- input
inputnew[select] <- NA

input
 [1] 20.2 20.2 20.2 20.2 20.1 20.2 20.2 20.1 20.2 20.2 20.2 20.2 17.7 18.9 19.3
 [16] 19.4 19.4 19.4 19.5 19.5 19.5

inputnew
 [1] 20.2 20.2 20.2 20.2 20.1 20.2 20.2 20.1 20.2 20.2 20.2 20.2   NA 18.9 19.3
 [16] 19.4 19.4 19.4 19.5 19.5 19.5

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM