Заполните NAs, сгладив пиковые значения

#r

Вопрос:

 df <- data.frame(date = seq(from=as.POSIXct(as.Date("2020-10-01")), 
                            to= as.POSIXct(as.Date("2020-10-02")) , by = 'hour'), 
               val = c(15,20,18,22,17,NA,NA,NA,80,14,23,16,19,21,NA,NA,60,18,15,20,22,19,NA,35,18))
 

Существуют неравномерные последовательности ‘NA, за которыми следуют пиковые значения, например: val = 80, 60 и 35 .

Я хотел бы заполнить пробелы, сгладив пиковые значения. Например: в первой последовательности NA за тремя NAs следует 80, что равно четырем точкам данных, следовательно, 80 делится на 4 = 20 .

Примечание: пиковые значения НЕ являются выбросами, поэтому общая сумма точек данных не должна изменяться.

Если возможно, я хотел бы заполнить NAs вышеуказанными условиями, сохранив поведение сигнала (тренд и сезонность).

Большое спасибо.

Комментарии:

1. Можем ли мы предположить, что пиковые значения всегда следуют за последовательностью NA «s», но никогда не предшествуют последовательности?

2. Да, они всегда так делают. Спасибо

Ответ №1:

Следующая функция заполняет последовательности NA значений следующим не — NA значением, деленным на длину последовательности.

 fill_na <- function(x){
  na <- is.na(x)
  r <- rle(na)
  div <- r$lengths[r$values]   1L
  cs <- cumsum(r$lengths)[r$values]
  for(i in seq_along(div)){
    if(cs[i] < length(x)){
      x[ (cs[i] - div[i]   1L):(cs[i]   1L) ] <- x[ cs[i]   1L ]/div[i]
    }
  }
  x
}

fill_na(df$val)
# [1] 15.0 20.0 18.0 22.0 20.0 20.0 20.0 20.0 20.0 14.0 23.0
#[12] 16.0 19.0 20.0 20.0 20.0 20.0 18.0 15.0 20.0 22.0 17.5
#[23] 17.5 17.5 18.0
 

Комментарии:

1. Спасибо вам за ваше решение, однако пиковое значение необходимо разделить, чтобы для первой последовательности (три NAs пик ) сумма всех четырех точек данных должна быть ровно 80 , до и после процесса.

2. @DAL ХОРОШО, исправлено сейчас, смотрите правку.

3. это здорово, спасибо.