这是开始使用data.table
:
billdata <- read.table(text=" acct amount begin end days
1 2242 11349 2009-10-06 2009-11-04 29
2 2242 12252 2009-11-04 2009-12-04 30
3 2242 21774 2009-12-04 2010-01-08 35
4 2242 18293 2010-01-08 2010-02-05 28
5 2243 27217 2009-10-06 2009-11-04 29
6 2243 117 2009-11-04 2009-12-04 30
7 2243 14543 2009-12-04 2010-01-08 35", sep=" ", header=TRUE, row.names=1)
require(data.table)
DT = as.data.table(billdata)
首先,变型列begin
和end
至日期。与data.frame不同,这不会复制整个数据集。
DT[,begin:=as.Date(begin)]
DT[,end:=as.Date(end)]
然后找到时间跨度,找到每天的主要账单,并进行汇总。
alldays = DT[,seq(min(begin),max(end),by="day")]
setkey(DT, acct, begin)
DT[CJ(unique(acct),alldays),
mean(amount/days,na.rm=TRUE),
by=list(acct,month=format(begin,"%Y-%m")), roll=TRUE]
acct month V1
1: 2242 2009-10 391.34483
2: 2242 2009-11 406.69448
3: 2242 2009-12 601.43226
4: 2242 2010-01 646.27465
5: 2242 2010-02 653.32143
6: 2243 2009-10 938.51724
7: 2243 2009-11 97.36172
8: 2243 2009-12 375.68065
9: 2243 2010-01 415.51429
10: 2243 2010-02 415.51429
我认为您会发现流行的连接逻辑在sql中非常麻烦,而且速度较慢。
我说这是一个提示,因为它不太正确。注意重复行10,因为帐户2243不会像帐户2242那样延伸到2010-02。要结束该rbind
行,您可以在每个帐户的最后一行中使用rolltolast
代替roll
。或alldays
按帐户而不是跨所有帐户创建。
看看上面的速度是否可以接受,我们可以从那里开始。
您可能会遇到1.8.2中的错误,该错误已在1.8.3中修复。我正在使用v1.8.3。
合并包含丢失的组和分组依据的联接时,“内部”错误消息已修复,编号#2162。例如:X [Y,.N,by = NonJoinColumn]其中Y包含一些与X不匹配的行。此错误也可能导致段错误。
让我知道,我们可以解决问题,也可以从R-Forge升级到1.8.3。
顺便说一句,很好的示例数据。这样可以更快地回答。
这是上面提到的完整答案。我不得不承认这有点棘手,因为它结合了的多个功能data.table
。它应该在1.8.2中正常工作,但我仅在1.8.3中进行了测试。
DT[ setkey(DT[,seq(begin[1],last(end),by="day"),by=acct]),
mean(amount/days,na.rm=TRUE),
by=list(acct,month=format(begin,"%Y-%m")), roll=TRUE]
acct month V1
1: 2242 2009-10 391.34483
2: 2242 2009-11 406.69448
3: 2242 2009-12 601.43226
4: 2242 2010-01 646.27465
5: 2242 2010-02 653.32143
6: 2243 2009-10 938.51724
7: 2243 2009-11 97.36172
8: 2243 2009-12 375.68065
9: 2243 2010-01 415.51429