注意:为方便起见,我使用上一篇文章中的示例数据集。
假设有两个数据集ref
和map
。他们是:
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))
他们看起来像是:
> 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
现在,我注意到在仍处于开发阶段的data.table包中,函数foverlaps
将在ref
中填充map
中的相应行。 }。
setkey(ref,space,t1,t2)
foverlaps(map,ref,type="within",nomatch=0L)
给出:
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
运行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)
我想做的是:
以上基本列出了时间间隔内包含的所有间隔。但是,我正在尝试按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
每个map
的每个时间间隔之间的ref
行数落在{{1}}之间。虽然我理解一个非常基本的解决方案是只使用求和或计数函数来计算,是否有一个解决方案可以创建计数而无需先创建更大的填充数据集?我这样说是因为我的真实数据包含超过3亿次观测。任何建议都会有很大帮助!谢谢!
答案 0 :(得分: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
然后在ref
中重新开始。但我们应该提供一种更直接的方法来实现这一目标。
答案 1 :(得分:2)
你可以这样做:
count <- function(x, y) map[,sum(t1>=x & t2<=y)]
ref[, count:=mapply(x=t1, y=t2, count)]
ref
space t1 t2 id count
1: nI 100 150 a 10
2: nI 300 400 b 20
3: nI 500 600 c 20
答案 2 :(得分:1)
为遗传数据开发的 Biocondcutor GenomicRanges软件包具有“空间”的概念。 (序列名称),空间内的坐标(整数范围定义为起始坐标和结束坐标的闭合间隔),以及元数据&#39;与每个范围关联的列。所以
library(GenomicRanges)
ref <- with(ref, GRanges(space, IRanges(t1, t2), id=id))
map <- with(map, GRanges(space, IRanges(t1, t2), res=rnorm(241)))
GenomicRanges支持许多基于范围的操作,包括
ref$count <- countOverlaps(ref, map)
要完成你感兴趣的事情(countOverlaps支持不同的重叠概念,所以默认(范围之间的任何重叠)可能不是你感兴趣的;一个范围是包含在内的&#39;它的开始和结束,但范围可以很容易地改变或缩小;这两者都可能意味着countOverlaps()
的直接应用与你期望的不同。
要处理大量数据,通过打开与数据源的连接并读取连续的行,或通过连续行读取数据块(例如,大型数据的10M行)是很自然的。对数据库或任何文件格式进行基于范围的查询。
con <- open("my.csv")
while (nrow(map0 <- read.csv(con, nrows=10000000))) {
map <- with(map0, GRanges(space, IRanges(t1, t2)))
ref$count <- ref$count + countOverlaps(ref, map)
}
close(con)