2014-09-26 61 views
0

我有一个大的合同日期表。在我的决赛桌上,我希望每个月都有一个合同活动的单一行。问题是我目前解决方案的速度。有没有更快的方法来实现这一目标? (我有超过1点百万ID的不同合约的运行时间,它需要几分钟的时间,我怀疑cbind?!)。加速日期转换data.table方式

library(data.table) 
dt <- data.table(id=c(123, 345), 
      start=c(as.IDate("2013-01-01"), as.IDate("2012-01-01")), 
      end=c(as.IDate("2013-04-01"),as.IDate("2012-02-01"))) 

dt[, cbind(.SD, seq(start, end, by="month")), by=id] 

    id  start  end   V2 
1: 123 2013-01-01 2013-04-01 2013-01-01 
2: 123 2013-01-01 2013-04-01 2013-02-01 
3: 123 2013-01-01 2013-04-01 2013-03-01 
4: 123 2013-01-01 2013-04-01 2013-04-01 
5: 345 2012-01-01 2012-02-01 2012-01-01 
6: 345 2012-01-01 2012-02-01 2012-02-01 
+1

您是否尝试过使用'dt [,seq(start,end,by =“month”),by = id]'生成月份,然后将它与原始数据结合? – ilir 2014-09-26 09:58:28

回答

3

的第一个想法:一对夫妇的扭动我能想到的。

  • 首先,我会使用seq.int代替seq,后者是一个S3泛型将需要一些时间调度,这可能是上万组昂贵。其次,我会使用1.9.3(这几乎是完整的,应该尽快推送到CRAN),这里有很多增强功能。

  • 第三,我会在j中使用c(.SD, seq.int(start, end, by="month")) - 这是在1.9.3内部优化的,因此会更快。

在本质上,试试这个在1.9.3:

dt[, c(.SD, seq.int(start, end, by="month")), by=id] 

当然,这上万组仍在运行,因此可能仍然会比较慢(即使比你以前的答案更快) 。不过,我很想知道这里的加速(如果有的话)。

但这里的真正的问题是,我们正在评估j-expression每组,和你有一百万of'em。如果seq.intfromto参数能够处理长度大于1的输入,那么理想情况是什么。但是,最有可能的是,您必须编写自己的C/C++代码才能实现。