2014-09-26 29 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++代碼才能實現。