在R.中分解data.frame对象中每月子时段的整个时段

时间:2013-08-12 08:00:03

标签: r date

我有以下data.frame(只有3个ID的示例):

> df
        ID  STARTDATE    ENDDATE
1 qwer.001 2014-01-01 2014-04-01
2 asdf.002 2014-04-01 2014-07-01
3 yxcv.003 2015-01-01 2015-03-01
...


> str(df)
'data.frame':   3 obs. of  3 variables:
 $ ID       : Factor w/ 3 levels "asdf.002","qwer.001",..: 2 1 3
 $ STARTDATE: Date, format: "2014-01-01" "2014-04-01" ...
 $ ENDDATE  : Date, format: "2014-04-01" "2014-07-01" ...

df(原始版本)有大约100k个唯一ID,每个ID都有一个START和END日期,并且只在data.frame中出现一次。 我需要按如下方式转换df

> df2 
        ID  STARTDATE    ENDDATE
1 qwer.001 2014-01-01 2014-02-01
2 qwer.001 2014-02-01 2014-03-01
3 qwer.001 2014-03-01 2014-04-01
4 asdf.002 2014-04-01 2014-05-01
5 asdf.002 2014-05-01 2014-06-01
6 asdf.002 2014-06-01 2014-07-01
7 yxcv.003 2015-01-01 2015-02-01
8 yxcv.003 2015-02-01 2015-03-01

每个ID的总时间分为每月子时段。 关于如何解决这个问题的任何提示或想法都表示赞赏。

1 个答案:

答案 0 :(得分:2)

以下是使用库ddply()中的函数plyr的解决方案。它使用原始STARTDATEENDDATE来生成日期序列,并使用tail()head()选择最后或第一个值。

library(plyr)
ddply(df,.(ID),function(x)
      data.frame(STARTDATE=head(seq(x$STARTDATE,x$ENDDATE,by="month"),-1),
      ENDDATE=tail(seq(x$STARTDATE,x$ENDDATE,by="month"),-1)))
        ID  STARTDATE    ENDDATE
1 asdf.002 2014-04-01 2014-05-01
2 asdf.002 2014-05-01 2014-06-01
3 asdf.002 2014-06-01 2014-07-01
4 qwer.001 2014-01-01 2014-02-01
5 qwer.001 2014-02-01 2014-03-01
6 qwer.001 2014-03-01 2014-04-01
7 yxcv.003 2015-01-01 2015-02-01
8 yxcv.003 2015-02-01 2015-03-01

由于您的数据框很大,您还可以查看库data.table以获得更快的解决方案。

library(data.table)
dt<-data.table(df)
dt[,list(STARTDATE=head(seq(STARTDATE,ENDDATE,by="month"),-1),
   ENDDATE=tail(seq(STARTDATE,ENDDATE,by="month"),-1))
   ,by="ID"]