我目前有两个data.table表。第一个看起来像:
> data1
Person Date
1 2007-1-1
2 2007-1-3
3 2007-1-9
4 2007-1-17
5 2007-1-30
第二个看起来像:
> data2
Person Date
1 2007-1-2
1 2007-1-3
1 2007-1-5
2 2007-1-4
2 2007-1-6
2 2007-1-7
2 2007-1-8
3 2007-1-19
4 2007-1-19
4 2007-1-25
5 2007-2-28
5 2007-3-5
我想:
Person Date Between
1 2007-1-1 1
2 2007-1-3 4
3 2007-1-9 0
4 2007-1-17 2
5 2007-1-30 2
在这里,我想看一下第一个data.table中的第一个人,看一下第一个人和第二个人之间的差距,以便差距是:2007-1-1到2007-1 -3。然后,我想对第二个人进行搜索,并返回第二个data.table中对应于人1的日期数在2007-1-1到2007-1-3之间。这里只有一个实例,所以我们在其间放置了一个实例。
对于第二种情况,第二个数据集中有四个实例,日期介于2007-1-3和2007-1-9之间,因此Between列取值4.对于最后一个实例,Person 5,我们认为2007-2-31和2007-3-5是第一个表格中人物5值的两个日期:2007-1-30。
我已经能够为此编写一个for循环,
vector.data <- rep(NA, 5)
for(i in 1:5){
index <- which(data1$date == data2$date)
data1[index,]
}
然而,我主要担心的是速度。我想为一个大约1亿行的数据集执行此操作。因此,我想知道是否有data.table解决方案或其他一些快速解决方案。谢谢!
答案 0 :(得分:1)
这似乎可以解决问题,并且应该相对较快:
> dt2$MaxDate = dt1[dt2$Person + 1, "Date"]
> dt2$MinDate = dt1[dt2$Person, "Date"]
> dt2[dt2$Person == max(dt2$Person),]$MaxDate = Sys.Date() #Last person can be any time
> dt2$IsBetween = with(dt2, Date > MinDate & Date < MaxDate)
所以这就是现在的表格:
> dt2
Person Date MaxDate MinDate IsBetween
1 1 2007-01-02 2007-01-03 2007-01-01 TRUE
2 1 2007-01-03 2007-01-03 2007-01-01 FALSE
3 1 2007-01-05 2007-01-03 2007-01-01 FALSE
4 2 2007-01-04 2007-01-09 2007-01-03 TRUE
5 2 2007-01-06 2007-01-09 2007-01-03 TRUE
6 2 2007-01-07 2007-01-09 2007-01-03 TRUE
7 2 2007-01-08 2007-01-09 2007-01-03 TRUE
8 3 2007-01-19 2007-01-17 2007-01-09 FALSE
9 4 2007-01-19 2007-01-30 2007-01-17 TRUE
10 4 2007-01-25 2007-01-30 2007-01-17 TRUE
11 5 2007-02-28 2014-09-17 2007-01-30 TRUE
12 5 2007-03-05 2014-09-17 2007-01-30 TRUE
使用tapply
对结果进行分组:
> dt1$Between = tapply(dt2$IsBetween, dt2$Person, sum)
> dt1
Person Date Between
1 1 2007-01-01 1
2 2 2007-01-03 4
3 3 2007-01-09 0
4 4 2007-01-17 2
5 5 2007-01-30 2
我使用了基础data.frame而不是data.table,因为相同的列名会使得范围混乱。在这种情况下,我认为表现应该没问题