在大型数据集上使用data.table - 需要添加自第一次出现组项以来表示#weeks的列

时间:2015-04-08 23:44:57

标签: r data.table

使用data.tables,我尝试添加一个新列,其中包含自分组发生事件以来的周数。 (注意:"周"之后,而不是差异(因此,从1开始,而不是零))

查看数据,我的期望可能会让您更容易看到...

我有以下数据集:

library(data.table) 
DT1 <-fread("OrderDate,EventDate,OrderID,EventTypeID,LocationID,EncounterID 
1/12/2012 5:40,01/12/2012 05:40,100001,12344,1,5998887
1/12/2012 5:41,01/12/2012 05:49,100001,12345,1,5998887
1/12/2012 5:42,01/12/2012 06:40,100001,12345,1,5998887
1/12/2012 5:45,01/12/2012 05:45,100002,12344,1,5998887
1/12/2012 5:45,01/12/2012 05:49,100002,12345,1,5998887
8/12/2013 5:25,01/12/2012 06:40,100002,12345,1,5998887
8/12/2013 5:46,01/12/2012 05:46,100003,12344,2,5998887
9/12/2013 5:46,01/12/2012 05:49,100003,12345,2,5998887
1/12/2013 7:40,01/12/2013 07:40,123001,12345,2,6008887
1/12/2013 7:40,01/12/2013 07:41,123001,12346,2,6008887
16/12/2013 7:40,01/12/2013 07:50,123001,12345,2,6008887
17/12/2013 7:40,01/12/2013 07:55,123001,12345,2,6008887")


DT$OrderDate <- as.POSIXct(DT$OrderDate, format="%d/%m/%Y %H:%M")
DT$EventDate <- as.POSIXct(DT$EventDate, format="%d/%m/%Y %H:%M")

我尝试做的是添加自第一次出现encounterID以来几周的列。

DT2 <- fread("OrderDate,EventDate,OrderID,EventTypeID,LocationID,EncounterID, WeeksSinceFirstEnc
1/12/2012 5:40,01/12/2012 05:40,100001,12344,1,5998887,1
1/12/2012 5:41,01/12/2012 05:49,100001,12345,1,5998887,1
1/12/2012 5:42,01/12/2012 06:40,100001,12345,1,5998887,1
1/12/2012 5:45,01/12/2012 05:45,100002,12344,1,5998887,1
1/12/2012 5:45,01/12/2012 05:49,100002,12345,1,5998887,1
8/12/2013 5:25,01/12/2012 06:40,100002,12345,1,5998887,1
8/12/2013 5:46,01/12/2012 05:46,100003,12344,2,5998887,2
9/12/2013 5:46,01/12/2012 05:49,100003,12345,2,5998887,2
1/12/2013 7:40,01/12/2013 07:40,123001,12345,2,6008887,1
1/12/2013 7:40,01/12/2013 07:41,123001,12346,2,6008887,1
16/12/2013 7:40,01/12/2013 07:50,123001,12345,2,6008887,3
17/12/2013 7:40,01/12/2013 07:55,123001,12345,2,6008887,3")

我在相当大的数据集上执行此操作,因此效率至关重要。而且,我希望尽可能使用data.table函数来做到这一点。

有谁能建议我如何才能有效地做到这一点?

2 个答案:

答案 0 :(得分:2)

我没有太多关于日期格式的练习,但这似乎有效:

DT1[,OrderDate:=as.Date(OrderDate,"%d/%m/%Y")]
setkey(DT1,EncounterID,OrderDate)
DT1[,w:=as.numeric(1L+floor((OrderDate-OrderDate[1])/7)),by=EncounterID]

setkey调用会对data.table进行排序,以使第一个日期为OrderDate[1]。如果这总是等于EventDate,那么您可以改为

DT1[,OrderDate:=as.Date(OrderDate,"%d/%m/%Y")]
DT1[,EventDate:=as.Date(EventDate,"%d/%m/%Y")]
DT1[,w:=as.numeric(1L+floor((OrderDate-EventDate)/7)),by=EncounterID]

答案 1 :(得分:2)

试试这个:

DT[, WeeksSinceFirstEnc := OrderDate - min(EventDate), by = EncounterID]
DT[, WeeksSinceFirstEnc := as.numeric(DT$WeeksSinceFirstEnc)%/%(60 * 60 * 24 * 7) + 1]

首先,我计算eache EncounterID的第一个EventDate与每行的OrderDate之间的差异。结果保存在新列中,但只需几秒钟。

第二步是使用整数除法运算符(%/%)将秒转换为周,然后再加1。

我使用了第二个代码块中的数据,我有54个,你有2个,因为EventDate的年份是2013年,而不是2012年。

更新:按照Jan的建议,我改变了我的答案以节省内存。