是否找到一种有效的方法来计算两个表中的时间间隔集之间的重叠数?

use*_*057 2 r data.table

注意:为了方便起见,我使用上一篇文章中的示例数据集。

假设有两个数据集,refmap。他们是:

ref <- data.table(space=rep('nI',3),t1=c(100,300,500),t2=c(150,400,600),id=letters[1:3])

map <- data.table(space=rep('nI',241),t1=seq(0,1200,by=5),t2=seq(5,1205,by=5),res=rnorm(241))
Run Code Online (Sandbox Code Playgroud)

他们看起来像:

> ref
   space t1  t2   id
1:    nI 100 150  a
2:    nI 300 400  b
3:    nI 500 600  c

> map
   space   t1   t2        res
1:    nI    0    5 -0.7082922
2:    nI    5   10  1.8251041
3:    nI   10   15  0.2076552
4:    nI   15   20  0.8047347
5:    nI   20   25  2.3388920
---                           
237:    nI 1180 1185  1.0229284
238:    nI 1185 1190 -0.3657815
239:    nI 1190 1195  0.3013489
240:    nI 1195 1200  1.2947271
241:    nI 1200 1205 -1.5050221
Run Code Online (Sandbox Code Playgroud)

现在,引起我注意的是,在仍在开发的data.table包中,该函数foverlapsref使用中的相应行填充间隔map

setkey(ref,space,t1,t2)

foverlaps(map,ref,type="within",nomatch=0L)
Run Code Online (Sandbox Code Playgroud)

这使:

   space t1  t2  id i.t1 i.t2         res
1:    nI 100 150  a  100  105 -0.85202726
2:    nI 100 150  a  105  110  0.79748876
3:    nI 100 150  a  110  115  1.49894097
4:    nI 100 150  a  115  120  0.47719957
5:    nI 100 150  a  120  125 -0.95767896
6:    nI 100 150  a  125  130 -0.51054673
7:    nI 100 150  a  130  135 -0.08478700
8:    nI 100 150  a  135  140 -0.69526566
9:    nI 100 150  a  140  145  2.14917623
10:    nI 100 150  a  145  150 -0.05348163
11:    nI 300 400  b  300  305  0.28834548
12:    nI 300 400  b  305  310  0.32449616
13:    nI 300 400  b  310  315  1.16107248
14:    nI 300 400  b  315  320  1.08550676
15:    nI 300 400  b  320  325  0.84640788
16:    nI 300 400  b  325  330 -2.15485447
17:    nI 300 400  b  330  335  1.59115714
18:    nI 300 400  b  335  340 -0.57588128
19:    nI 300 400  b  340  345  0.23957563
20:    nI 300 400  b  345  350 -0.60824259
21:    nI 300 400  b  350  355 -0.84828189
22:    nI 300 400  b  355  360 -0.43528701
23:    nI 300 400  b  360  365 -0.80026281
24:    nI 300 400  b  365  370 -0.62914234
25:    nI 300 400  b  370  375 -0.83485164
26:    nI 300 400  b  375  380  1.46922713
27:    nI 300 400  b  380  385 -0.53965310
28:    nI 300 400  b  385  390  0.98728765
29:    nI 300 400  b  390  395 -0.66328893
30:    nI 300 400  b  395  400 -0.08182384
31:    nI 500 600  c  500  505  0.72566100
32:    nI 500 600  c  505  510  2.27878366
33:    nI 500 600  c  510  515  0.72974139
34:    nI 500 600  c  515  520 -0.35358019
35:    nI 500 600  c  520  525 -1.20697646
36:    nI 500 600  c  525  530 -0.01719057
37:    nI 500 600  c  530  535  0.06686472
38:    nI 500 600  c  535  540 -0.40866088
39:    nI 500 600  c  540  545 -1.02697573
40:    nI 500 600  c  545  550  2.19822065
41:    nI 500 600  c  550  555  0.57075648
42:    nI 500 600  c  555  560 -0.52009726
43:    nI 500 600  c  560  565 -1.82999177
44:    nI 500 600  c  565  570  2.53776578
45:    nI 500 600  c  570  575  0.85626293
46:    nI 500 600  c  575  580 -0.34245708
47:    nI 500 600  c  580  585  1.21679869
48:    nI 500 600  c  585  590  1.87587020
49:    nI 500 600  c  590  595 -0.23325264
50:    nI 500 600  c  595  600  0.18845022
space  t1  t2 id i.t1 i.t2         res
Run Code Online (Sandbox Code Playgroud)

要运行data.table 1.9.3的开发版本,以下代码将帮助您运行它:

install.packages("devtools")
library(devtools)
dev_mode(on=T)

install_github("Rdatatable/data.table", build_vignettes=FALSE)

dev_mode(on=F)
Run Code Online (Sandbox Code Playgroud)

我正在尝试做的是:

以上基本上列出了时间间隔内包含的所有间隔。不过,我想只需要创建一个新的列ref计数的行数map是的时间间隔内ref。因此,我想要的表是:

> ref
   space t1  t2  id  count
1:    nI 100 150  a     10
2:    nI 300 400  b     20
3:    nI 500 600  c     20
Run Code Online (Sandbox Code Playgroud)

每个的计数表示map在的每个时间间隔之间落入了多少行ref。虽然我知道一个非常基本的解决方案是仅使用求和或计数函数进行计数,但是有没有一种解决方案可以创建计数而不必先创建较大的填充数据集?我之所以这样说,是因为我的真实数据包含超过3亿个观测值。任何建议将大有帮助!谢谢!

Aru*_*run 5

您可以使用which=TRUE参数获取重叠的位置,然后通过进行简单的汇总来获取计数

ans = foverlaps(map, ref, type="within", nomatch=0L, which=TRUE)[, .N, by=yid]
#    yid  N
# 1:   1 10
# 2:   2 20
# 3:   3 20
Run Code Online (Sandbox Code Playgroud)

然后将其恢复ref。但是,我们应该提供一种更直接的方法来实现这一目标。