0

我有以下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 的整个周期被细分为每月的子周期。任何关于我如何解决这个问题的提示或想法都值得赞赏。

4

1 回答 1

2

这是使用ddply()库中的函数的解决方案plyr。它使用原始STARTDATEandENDDATE来制作日期序列,并使用tail()or 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"]
于 2013-08-12T08:10:37.363 回答