有没有一种快速的方法在一个data.table中搜索值,然后比较它/将它工作到另一个data.table?

时间:2014-09-17 20:22:18

标签: r data.table

我目前有两个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解决方案或其他一些快速解决方案。谢谢!

1 个答案:

答案 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,因为相同的列名会使得范围混乱。在这种情况下,我认为表现应该没问题