我有以下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的总时间分为每月子时段。 关于如何解决这个问题的任何提示或想法都表示赞赏。
答案 0 :(得分:2)
以下是使用库ddply()
中的函数plyr
的解决方案。它使用原始STARTDATE
和ENDDATE
来生成日期序列,并使用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"]