R中的data.table:从x到i

时间:2018-12-05 10:01:50

标签: r performance data.table

我有两个数据表

a <- data.table(id=c(1,2,1,2,1,2), time=as.POSIXct(c("2018-01-01 01:10:00","2018-01-01 01:10:00","2018-01-01 01:11:00","2018-01-01 01:11:00","2018-01-01 01:12:00","2018-01-01 01:12:00")), beg=as.POSIXct(c("2018-01-01 01:00:00","2018-01-01 01:05:00","2018-01-01 01:00:00","2018-01-01 01:05:00","2018-01-01 01:01:00","2018-01-01 01:05:00")), end=as.POSIXct(c("2018-01-01 02:00:00","2018-01-01 02:05:00","2018-01-01 02:00:00","2018-01-01 02:05:00","2018-01-01 02:00:00","2018-01-01 02:05:00")))

> a
   id                time                 beg                 end
1:  1 2018-01-01 01:10:00 2018-01-01 01:00:00 2018-01-01 02:00:00
2:  2 2018-01-01 01:10:00 2018-01-01 01:05:00 2018-01-01 02:05:00
3:  1 2018-01-01 01:11:00 2018-01-01 01:00:00 2018-01-01 02:00:00
4:  2 2018-01-01 01:11:00 2018-01-01 01:05:00 2018-01-01 02:05:00
5:  1 2018-01-01 01:12:00 2018-01-01 01:01:00 2018-01-01 02:00:00
6:  2 2018-01-01 01:12:00 2018-01-01 01:05:00 2018-01-01 02:05:00

具有650m行4列的行,并且

b <- data.table(id=c(1,2), abeg=as.POSIXct(c("2018-01-01 01:10:00","2018-01-01 01:11:00")), aend=as.POSIXct(c("2018-01-01 01:11:00","2018-01-01 01:12:00")))

> b
   id                abeg                aend
1:  1 2018-01-01 01:10:00 2018-01-01 01:11:00
2:  2 2018-01-01 01:11:00 2018-01-01 01:12:00

大约有1300万行乘以7列。

我想将b加入a,但保留a的所有行和列。我了解这是一个左联接,可以将其执行为

b[a, .(id=i.id, time=i.time, beg=i.beg, end=i.end, abeg=x.abeg, aend=x.aend), on=.(id=id, abeg<=time, aend>=time)]

获得

   id                time                 beg                 end                abeg                aend
1:  1 2018-01-01 01:10:00 2018-01-01 01:00:00 2018-01-01 02:00:00 2018-01-01 01:10:00 2018-01-01 01:11:00
2:  2 2018-01-01 01:10:00 2018-01-01 01:05:00 2018-01-01 02:05:00                <NA>                <NA>
3:  1 2018-01-01 01:11:00 2018-01-01 01:00:00 2018-01-01 02:00:00 2018-01-01 01:10:00 2018-01-01 01:11:00
4:  2 2018-01-01 01:11:00 2018-01-01 01:05:00 2018-01-01 02:05:00 2018-01-01 01:11:00 2018-01-01 01:12:00
5:  1 2018-01-01 01:12:00 2018-01-01 01:01:00 2018-01-01 02:00:00                <NA>                <NA>
6:  2 2018-01-01 01:12:00 2018-01-01 01:05:00 2018-01-01 02:05:00 2018-01-01 01:11:00 2018-01-01 01:12:00

但是,当我不得不中止时,在Mac上执行此操作要花费超过7个小时的时间。我加入了a的50m行子集,这花了大约8分钟。我想避免子集上的循环,所以我想知道是否可以提高效率。

例如,我怀疑分配命令:=可以以某种方式使用。在data.table join then add columns to existing data.frame without re-copy中,说明了如何{{1}中的所有变量都保留并修改b中的变量时如何进行。但是,我似乎遇到了相反的情况:我想将所有列都保留在a中,并用a中的列进行修改。

1 个答案:

答案 0 :(得分:0)

这里有一个引用更新,我认为您打算做什么:

a[b, on=.(id=id, time>=abeg, time<=aend), `:=`(abeg = i.abeg, aend = i.aend)]

然后得到的a是:

   id                time                 beg                 end                abeg                aend
1:  1 2018-01-01 01:10:00 2018-01-01 01:00:00 2018-01-01 02:00:00 2018-01-01 01:10:00 2018-01-01 01:11:00
2:  2 2018-01-01 01:10:00 2018-01-01 01:05:00 2018-01-01 02:05:00                <NA>                <NA>
3:  1 2018-01-01 01:11:00 2018-01-01 01:00:00 2018-01-01 02:00:00 2018-01-01 01:10:00 2018-01-01 01:11:00
4:  2 2018-01-01 01:11:00 2018-01-01 01:05:00 2018-01-01 02:05:00 2018-01-01 01:11:00 2018-01-01 01:12:00
5:  1 2018-01-01 01:12:00 2018-01-01 01:01:00 2018-01-01 02:00:00                <NA>                <NA>
6:  2 2018-01-01 01:12:00 2018-01-01 01:05:00 2018-01-01 02:05:00 2018-01-01 01:11:00 2018-01-01 01:12:00