Вписать отсутствующие переменные, но не в начале и в конце?

Рассмотрим следующий рабочий пример:

library(data.table)
library(imputeTS)

DT <- data.table(
  time = c(1:10),
  var1 = c(1:5, NA, NA, 8:10),
  var2 = c(NA, NA, 1:4, NA, 6, 7, 8),
  var3 = c(1:6, rep(NA, 4))
)

        time var1 var2 var3
 1:    1    1   NA    1
 2:    2    2   NA    2
 3:    3    3    1    3
 4:    4    4    2    4
 5:    5    5    3    5
 6:    6   NA    4    6
 7:    7   NA   NA   NA
 8:    8    8    6   NA
 9:    9    9    7   NA
10:   10   10    8   NA

Я хочу вменять недостающие значения в различные моменты временного ряда, используя na_interpolation из пакета imputeTS. Однако я не хочу вменять недостающие значения в начале или в конце ряда, которые могут иметь разную длину (в моем приложении замена этих значений не имела бы смысла).

Когда я запускаю следующий код для вменения серии, все НО заменяются:

DT[,(cols_to_impute_example) := lapply(.SD, na_interpolation), .SDcols = cols_to_impute_example]
> DT
    time var1 var2 var3
 1:    1    1    1    1
 2:    2    2    1    2
 3:    3    3    1    3
 4:    4    4    2    4
 5:    5    5    3    5
 6:    6    6    4    6
 7:    7    7    5    6
 8:    8    8    6    6
 9:    9    9    7    6
10:   10   10    8    6

Я хочу добиться:

    time var1 var2 var3
 1:    1    1   NA    1
 2:    2    2   NA    2
 3:    3    3    1    3
 4:    4    4    2    4
 5:    5    5    3    5
 6:    6    6    4    6
 7:    7    7    5   NA
 8:    8    8    6   NA
 9:    9    9    7   NA
10:   10   10    8   NA

3 ответа

Решение

Библиотека зоопарка предлагает функцию интерполяции, которая позволяет настраивать больше:

library(zoo)
DT[,(2:4) := lapply(.SD, na.approx, x = time, na.rm = FALSE), .SDcols = 2:4]

Возможно, не так хорошо известно, вы также можете использовать дополнительные параметры из примерно в na.interpolationфункция imputeTS.

Это можно решить с помощью:

library(imputeTS)
DT[,(2:4) := lapply(.SD, na_interpolation, yleft = NA , yright = NA), .SDcols = 2:4]

Здесь с yleft а также yright вы указываете, что делать с замыкающими / ведущими НП.

Что приводит к желаемому результату:

time var1 var2 var3
 1:    1    1   NA    1
 2:    2    2   NA    2
 3:    3    3    1    3
 4:    4    4    2    4
 5:    5    5    3    5
 6:    6    6    4    6
 7:    7    7    5   NA
 8:    8    8    6   NA
 9:    9    9    7   NA
 10:   10   10    8   NA

Практически почти все параметры, которые вы найдете на approx Описание функции также может быть передано функции na.interpolation в качестве дополнительных параметров для точной настройки.

Реализация dplyr: мы выбираем среднюю часть df, где мы выполняем интерполяцию NA, а затем связываем ее обратно.

  library(imputeTS)
  library(dplyr)

  DT <- data_frame(
    time = c(1:10),
    var1 = c(1:5, NA, NA, 8:10),
    var2 = c(NA, NA, 1:4, NA, 6, 7, 8),
    var3 = c(1:6, rep(NA, 4))
  )

  na_inter_middle<-function(row_start, row_end){

  # extracts the first part of the df where no NA need to be replaced
  DT[1:row_start,]->start 
  # middle part, interpolating NA values
  DT[(row_start + 1):(nrow(DT) - row_end),]->middle
  #end part
  DT[(nrow(DT) - (row_end - 1) ):nrow(DT),]->end


  start %>% 
    bind_rows(

  middle %>% 
    mutate_all(na.interpolation)

    ) %>% 
    bind_rows(end)

  }

  na_inter_middle(2,3)  


# A tibble: 10 x 4
    time  var1  var2  var3
   <int> <dbl> <dbl> <dbl>
 1     1     1    NA     1
 2     2     2    NA     2
 3     3     3     1     3
 4     4     4     2     4
 5     5     5     3     5
 6     6     5     4     6
 7     7     5     4     6
 8     8     8     6    NA
 9     9     9     7    NA
10    10    10     8    NA
Другие вопросы по тегам