R在已经包含NA的系列中设置时间序列NA的异常值

时间:2017-08-15 09:06:27

标签: r time-series na outliers

我有一个包含NA的时间序列和一些突然跳跃:

int posX = 100;
int posX2 = 1820;
int dirX = 1;
int dirX2 = 1;
boolean drawforest = true;
int height = 1080;
int width = 1920;
//img = loadImage("BlueMorpho.png");
PImage img;
int storrelse = 15;
int storrelse2 = storrelse + 2;
float skift = random(0,2);

//setup()-metoden køres én gang, når sketchen startes
void drawBackground()
{
  color e = color(135, 206, 235);
  fill(e);
  rect(960, 270, 1920, 560);
}
void setup()
{
  size(1920, 1080); 
  rectMode(CENTER);
  drawBackground();
  color f = color(1, 142, 14);
  fill(f);
  rect(960, 820, 1920, 540);
  //noLoop();
}


//draw()-metoden kører i et loop, indtil den stoppes
void draw()
{
  switch(skift)
  {
  case 0:
    img = loadImage("BlueMorpho.png");
    break;
  case 1:
    img = loadImage("BlueMorpho2.png");
    break;
  default:
    img = loadImage("BlueMorpho3.png");
    break;
  }



  if (drawforest)
  {
    drawForest(); 
    drawforest = false;
  }
  drawBackground();
  drawCloud();
  drawCloud2();
  posX = posX+1;
  posX2 = posX2-1;
  if (posX>width-20 || posX<20)
  {
    dirX=-dirX;
  }
  if (posX2>width-20 || posX<20)
  {
    dirX2=-dirX2;
  }
}


void drawForest()
{
  for (int i = 0; i < 12; i++)
  {
    drawTree(random(55, 1865), 635 + 30*i);
  }
}

void drawTree(float xx, float yy)
{
  color c = color(139, 69, 19);
  fill(c);
  //noStroke();
  rect(xx, yy+30, 50, 100);
  color d = color(000, random(25, 100), 000);
  fill(d);
  //noStroke();
  ellipse(xx, yy-30, 125, 100);
  color g = color(100, 0, 0);
  fill(g);
  ellipse(random(xx-50, xx+50), random(yy-50, yy+18), 10, 10);
}

void drawCloud()
{
  color h = color(255, 255, 255);
  fill(h);
  ellipse(posX, 150, 100, 50);
  //posX += random(50,1920);
  noStroke();
}
void drawCloud2()
{
  color h = color(0, 0, 0);
  fill(h);
  ellipse(posX2, 200, 100, 50);
  //posX += random(50,1920);
}

void tegnSommerfugl(float xx, float yy)
{
  image(img, xx, yy, width/storrelse2, height/storrelse);
}

void mouseClicked()
{
  tegnSommerfugl(mouseX,mouseY);
}

其中7,0,9将被视为跳跃,其中0应由NA替换。

我想删除突然跳转的第一个值(设置值为跳转的设置值,在示例中为更改&gt; 1)并将其设置为NA

示例的输出应如下所示:

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

我只想设置异常值NA,我不想覆盖剩余的值。 跳跃可以是消极的也可以是积极的。

我遇到的问题:

  1. 将现有NA值计为跳转后的值
  2. 异常值被计为跳跃后“跳回”
  3. 这两个都导致了超过必要的NA,我尽量保留尽可能多的原始数据。

    有什么想法吗?我被困了一段时间。提前谢谢!

2 个答案:

答案 0 :(得分:1)

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

情况1

如果模式总是在几次中断时跳回到1 - 增加,我会创建类似于完美向量的vector_checkinput中与此不相符的所有内容都应设置为NA

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

情况2

如果模式不太可预测,你基本上希望寻找不规则的&#39;模式,你会得到一个更复杂的情况。一种可能的解决方案是创建一个while循环来检查哪些增量大于2(或任何值似乎合理的值),然后用bump_inds替换有问题的位置NA。在这里,我假设异常值产生两个大的增量:一个因为值突然下降(增加)而另一个因为它上升(下降)回到其旧值。这个过程一直持续到没有问题的位置为止:

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

Situation3

第三个选项,基于您的真实数据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

答案 1 :(得分:1)

这可能是一个更强大的解决方案,因为您可以根据需要修改以下数据的线性模型:

您的数据:

 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