【问题标题】:Impute missing variables but not at the beginning and the end?估算缺失的变量,但不在开头和结尾?
【发布时间】:2020-01-17 04:18:19
【问题描述】:

考虑以下工作示例:

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

我想使用 imputeTS 包中的 na_interpolation 估算时间序列内不同点的缺失值。但是,我不想在系列的开头或结尾估算可能有不同长度的缺失值(在我的应用程序中替换这些值没有意义)。

当我运行以下代码来估算系列时,所有 NA 都被替换:

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

【问题讨论】:

  • library(zoo); DT[,(2:4) := lapply(.SD, na.approx, x = time, na.rm = FALSE), .SDcols = 2:4]
  • 谢谢,这很好用。如果您对此做出回答,我将接受它作为解决方案。

标签: r missing-data imputation imputets


【解决方案1】:

一个 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

【讨论】:

  • 感谢您的回答。在我的应用程序中,我有数百个列/时间序列,因此手动指定行开始是不可行的。我认为 zoo 包的 na.approx (正如 Roland 之前评论的那样)似乎是解决方案。
【解决方案2】:

Library zoo 提供了允许更多自定义的插值函数:

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

【讨论】:

  • 在文档中很难找到,但可以用 imputeTS 以类似的方式完成:DT[,(2:4) := lapply(.SD, na_interpolation, yleft = NA , yright = NA), .SDcols = 2:4] 对于 imputeTS 和 zoo,也可以使用 approx 函数本身的参数- 有时这在这种情况下非常有用。
【解决方案3】:

也许不太为人所知,您还可以在 imputeTSna.interpolation 函数中使用来自 approx 的附加参数。

这个可以解决:

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

在这里,yleftyright 您指定如何处理尾随/前导 NA。

这会导致所需的输出:

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 函数以进行微调。

【讨论】:

    猜你喜欢
    • 2018-08-03
    • 1970-01-01
    • 2016-11-18
    • 2019-12-23
    • 2014-04-12
    • 1970-01-01
    • 1970-01-01
    • 2019-04-25
    相关资源
    最近更新 更多