微信号:gh_a9d9c3cb1ca5

介绍:市面上的教材太水?学了半天还是不知道如何处理工作中的数据?大猫的R语言课堂每期都和你分享一个工作研究中的实际问题,期期干货,就是这么实在!

一行代码对日期插值

2017-05-08 21:25 大猫

题引入

对日期进行插值是一项非常常见的任务。很多时候我们手头的时间序列都是不完整的,当中总会因为这样那样的原因漏了几天的观测,例如股票停牌了,观测仪器坏了,值班工人生病了等等。在分析时,我们为了获得完整的时间序列就需要“插入”那些丢失的日期。


举一个例子:


这个数据集中有5行观测,2组分类(id等于1和2)。我们看到每个id对应的date都是有缺失的,例如从2001-01-09直接跳到了2001-01-12,当中少了10号和11号。


如何只用一行代码就高效优美地把这些缺失的日期补上呢?


附:生成样例数据集的文件:


# sample dataset

# id变量用于分组

dt <- data.table(id = c(1, 1, 1, 2, 2), date = c(as.Date("2000-01-09"), as.Date("2000-01-12"), as.Date("2000-01-14"), as.Date("2000-02-09"), as.Date("2000-02-12")), val = rnorm(5))



本文需要用到data.table包!


况1:每个group起讫时间相等

首先来说第一种情况,在这种情况下,每个id都对应着“相同”的日期起讫点,例如,全都是从2000-01-08至2000-02-13。此时,我们相当于要构造出一个“平衡的”面板数据。


解决思路是运用data.table包的merge功能。首先我们建立一个CJ(cross join)数据集,这个数据集包含每个id所对应的“完整”日期

# 建立“完整”的日期序列

CJ <- CJ(id = unique(dt$id), 

    date = seq(as.Date("2000-01-08"), 

    as.Date("2000-02-13"), 

    by = "day"))


CJ数据集长这个样子(节选前11行和后11行):



我们看到CJ数据集中,每个id所对应的时间都被填充完整了。


(在建立CJ数据集的过程中,我们使用了seq函数来建立完整的时间序列)


接下来,我们把CJ数据集merge回原来的数据集dt。在merge的过程中,我们指定id和date变量必须匹配,也即on = .(id, date)语句的作用:


# 把CJ函数merge回原始数据集

dt[CJ, on = .(id, date), nomatch = NA]


结果为:



我们看到,原数据集存在观测的那些日期,val值都被保留,而被插入的那些日期,val是NA。当然,我们可以修改上一条语句中的nomatch参数把填充指改成任意值,例如0。


况2:每个group起讫时间不等

另一种情况是每个group的起讫时间不等。例如,在我们的样例数据集sample中,id=1的观测对应的日期最小值的为01-08,最大值为01-14,而我们希望填充这两个日期“之间”的所有值。同理,对于id=2的观测,日期最大值为02-09,最小值为02-12,我希望填充就是02-10,02-11这两天。


思路和情况1类似,我们先构造CJ数据集,只不过在这里我们seq函数的起讫点不再是固定值,而是每个id对应日期的最大值最小值


# 建立完整的日期序列

# 注意min和max函数的作用

CJ <- dt[, .(date = seq(min(date), 

    max(date), by = "day")), 

    keyby = id]


接下来我们把CJ数据集merge回dt数据集:


# 把CJ数据集merge回dt数据集

dt[CJ, on = .(id, date), nomatch = NA]


结果是:



大功告成!


等等,你不是说可以在一行当中搞定的吗?当然没问题,以上文提到的第二种情况为例,我们可以把两行合并为一行:


# 把两行代码合并成一行

dt[dt[, .(date = seq(min(date), 

    max(date), by = "day")),

    keyby = id], 

    on = .(id, date), 

    nomatch = NA]


这也是大猫喜欢data.table的一个原因:由于语法的灵活性,可以少生成很多中间数据集,这样也就不用绞尽脑汁为那些中间数据集命名了。处女座无数次为了给数据集取一个合适的名字心力交瘁……


期预告

根据官网公告,Microsoft R Open 3.4版本将会“coming soon in May”,大猫会在第一时间给大家发布号外~



 

大猫的R语言课堂


我是大猫,我是一个高中读文科但却在代码、数学的路上狂奔不止的Finance Ph. D Candidate。


我的微信号是iRoss2007


我的R语言课堂关注R语言、数据挖掘以及经济金融学。


我与大家分享我的知识,我相信独乐乐不如众乐乐


我还有许多好玩的计划。


更多的精彩内容正在路上。

长按二维码关注
 
大猫的R语言课堂 更多文章 【进阶】Next N rows when condition is 【速览】微软2017春季教育产品线发布会 Azure云中配置R Server 10行代码搞定【滚动回归】 一行代码搞定分组回归
猜您喜欢 斐波那契数列型-从数学角度学习 Swift 序列 纯干货:听赶集、美丽说、唱吧、春雨医生创始人谈创业维艰 【扯淡篇】从苦逼运维中的寻找美感 【译】测试Python 里的竞态条件 理解ionic2 + angular2开发方案