使用LCOF和NOCB方法填写时间序列差距,但确认时间序列中断

时间:2015-11-19 16:08:43

标签: r time-series zoo missing-data

最后对这篇文章进行了编辑。

我有大量个人人口日常膳食记录数据集。每个人都有随机丢失的数据。这是一个人的例子(我最终将这个解决方案推广到人口):

> str(final_daily)
'data.frame':   387 obs. of  10 variables:
 $ Date             : chr  "2014-08-13" "2014-08-14" "2014-08-15" "2014-08-16" ...
 $ MEID.1           : Factor w/ 97 levels "","1","1.1","1.1a",..: NA NA NA 17 24 NA NA NA NA NA ...
 $ MEID.2           : Factor w/ 184 levels "1","100","100.1",..: NA NA NA 143 48 NA NA NA NA NA ...
 $ MEID.3           : Factor w/ 180 levels "100","100.1",..: NA NA NA 24 134 NA NA NA NA NA ...
 $ MEID.4           : Factor w/ 42 levels "173","173a","173b",..: NA NA NA 17 1 NA NA NA NA NA ...
 $ MEID.5           : Factor w/ 3 levels "d1","s1","s2": NA NA NA 2 3 NA NA NA NA NA ...
 $ MEID.6           : Factor w/ 1 level "s2": NA NA NA NA NA NA NA NA NA NA ...
 $ DAYT             : int  NA NA NA 1 8 NA NA NA NA NA ...
 $ DATT             : int  NA NA NA 1 1 NA NA NA NA NA ...
 $ Reason.For.Change: chr  "0" "0" "0" "0" ...

我知道可以用来填补缺失数据的实现,例如最后一次观察结转(LOCF)和下一次观察结果(NOCB)。重要的是,缺失的数据缺口可以存在于一个日期,一次最多几个月。

我想创建一种插补方法,在缺失时间段的前半部分使用LOCF,在缺失时间段的后半部分使用NOCB。这对于大的时间序列差距更为重要(我不想在2月28日使用饮食摄入量来代表8月1日,当8月2日可用时)。有人可以在这里建议一个可能的解决方案吗?

重要的是,我还有一个列(Reason.For.Change),它应该限制Filling in missing (blanks) in a data table, per category - backwards and forwards中的插补方法。例如,当Reason.For.Change的值> 0时,插补应识别出这一点。换句话说,Reason.For.Change值> 0表示在Reason.For.Change> 0的那一天开始的个体内的“不同”时间序列,并且这些时间序列必须分别估算。

本质上,此列创建了两个条件:当记录不可用时,Reason.For.Change为> 0的日期之前的日期,只能使用LOCF。其次,由于在Reason.For.Change> 0的同一天没有饮食摄入记录,因此只能使用NOCB。 (这第二个例子与Filling in missing (blanks) in a data table, per category - backwards and forwards中的例子类似,患者在第一次就诊时缺少“医生”。)

赞赏任何建议/方向以完成以下我总结的以下内容

  1. 时间序列间隙的插补方法,包括LOCF和     NOCB的第一个和最后50%的差距
  2. 1)中的插补方法,用于确认时间序列中的中断 在日期上用值> 0表示并且允许LOCF上升到'break-date'并且NOCB填充回到并包括break-date
  3. [编辑]在考虑了一些之后,R -- Carry last observation forward n timesFill NA in a time series only to a limited number中的实现似乎在我的问题中提供了解决问题的方向1)。但是,我想概括他们使用LOCF n次到LOCF的长度(缺少数据)/ 2 ......

    [编辑2]在考虑了更多之后,我在我的数据框GAP_DAYS中添加了一个新列,它计算了缺失时间段(间隙)中的天数。添加新列后,数据上的str()。

    > str(final_daily_intake2)
    'data.frame':   387 obs. of  11 variables:
     $ Date             : chr  "2014-08-13" "2014-08-14" "2014-08-15" "2014-08-16" ...
     $ MEID.1           : chr  NA NA NA "14" ...
     $ MEID.2           : Factor w/ 184 levels "1","100","100.1",..: NA NA NA 143 48 NA NA NA NA NA ...
     $ MEID.3           : Factor w/ 180 levels "100","100.1",..: NA NA NA 24 134 NA NA NA NA NA ...
     $ MEID.4           : Factor w/ 42 levels "173","173a","173b",..: NA NA NA 17 1 NA NA NA NA NA ...
     $ MEID.5           : Factor w/ 3 levels "d1","s1","s2": NA NA NA 2 3 NA NA NA NA NA ...
     $ MEID.6           : Factor w/ 1 level "s2": NA NA NA NA NA NA NA NA NA NA ...
     $ DAYT             : int  NA NA NA 1 8 NA NA NA NA NA ...
     $ DATT             : int  NA NA NA 1 1 NA NA NA NA NA ...
     $ Reason.For.Change: chr  "0" "0" "0" "0" ...
     $ GAP_Days         : chr  "1" "2" "3" "NA" ...
    

    我认为这可用于确定每个差距期间使用LOCF的n天数。例如,在第一个缺失数据时间段内,缺少3天(因此在GAP_Days的str()中缺少1,2,3)。在这个例子中,由于它是奇数天,我希望LOCF使用round(3 * 0.5)的结果来获得值2,它将用作LOCF的输入。例如,在较长的时间段内,如果GAP_Days的长度为30,则LOCF将使用舍入(30 * 0.5)的结果,使得LOCF将使用15天。

    我认为这种方法可以用于使用LOCF重复一次数据帧,然后第二次使用NOCB。 (虽然我还没有解决在Reason.For.Change表示的时间序列中确认中断的需要)。 非常感谢。

1 个答案:

答案 0 :(得分:0)

由于文字很长,我会再次指出问题:

  
      
  1. 时间序列差距的插补方法,包括LOCF和NOCB的第一个和最后50%的差距

  2.   
  3. 1)中的估算方法,其确认日期中由值> 0表示的时间序列中的中断,并且允许LOCF上升到“休息日期”并且NOCB填充回到并包括中断 - 日期

  4.   

据我所知,R没有可用的软件包,它直接使您可以执行其中一项任务。

至1): 有很多软件包包含一个locf选项:

  • imputeTS :: na.locf()
  • zoo :: na.locf()
  • XTS :: na.locf()
  • 时空:: na.locf()

确实,你的归责想法非常有意义。 但是没有一个软件包可以为您请求的行为提供选项。你可以做什么,例如zoo设置 maxgap 参数。然后保留超过maxgap NAs的运行。这意味着您可以/之后必须单独处理它们。 您必须自己编写所请求的行为。

另一个想法可能是使用这些封装的其他更高级的功能,这些功能利用了NA间隙的两面。

一个例子是imputeTS :: na.ma(),它用移动平均值来计算值(你可以设置窗口大小)。

还有更高级的功能,如

  • imputeTS :: na.kalman()
  • imputeTS :: na.interpolation()
  • 预测:: na.interp()
  • 动物园:: na.StructTS()

这些还考虑了saisonal行为(工作日模式)和趋势等。这些问题当然不像locf或ma这样的简单算法那么简单。

至2): 这也没有预制功能。这也必须单独编码。