查找 R 中不是时间或基因组的整数重叠范围的值
Find value of overlapping ranges of integers in R that are NOT times or genomes
我正在尝试计算海洋物种和人类活动的重叠深度范围。所以对于每个物种,它都有一个最小和最大深度,我想有效地计算与 4 种不同活动的深度范围重叠的深度范围。我认为这可以用 data.table::foverlaps()
或 IRanges::findOverlaps()
来完成,但我不知道如何计算重叠的值,而不仅仅是它是真还是假。因此,如果在 40-100 米深度之间发现物种 D,并且 activity 1 出现在 0-50 米深度,则重叠为 10 米。
例如,
min_1 <- 0
max_1 <- 50
min_2 <- 0
max_2 <- 70
min_3 <- 0
max_3 <- 200
min_4 <- 0
max_4 <- 500
activities <- data.frame(min_1, max_1, min_2, max_2, min_3, max_3, min_4, max_4)
spp_id <- c("a", "b", "c", "d")
spp_depth_min <- c(0, 20, 30, 40)
spp_depth_max <- c(200, 500, 50, 100)
species <- data.frame(spp_id, spp_depth_min, spp_depth_max)
## data.table approach?
setDT(activities)
setDT(species)
foverlaps(species, activities, ...) ## Or do I need to subset each activity and do separate calculations?
写一个函数会不会更简单?我真的很陌生!这似乎应该是一件 common/easy 事情,我不知道为什么它让我如此困惑
我将你的活动 table 重组为一个长表格,这样你就可以一次完成所有 4 项计算。然后overlaps join就完成了,然后就可以根据结果计算出overlap的长度了。
activities <- data.table(
act = c('act_1','act_2','act_3','act_4'),
a_min = c(min_1, min_2, min_3, min_4),
a_max = c(max_1, max_2, max_3, max_4)
)
spp_id <- c("a", "b", "c", "d")
spp_depth_min <- c(0, 20, 30, 40)
spp_depth_max <- c(200, 500, 50, 100)
species <- data.table(spp_id, spp_depth_min, spp_depth_max)
setkey(activities,a_min,a_max)
ol <- foverlaps(species, activities,
by.x = c('spp_depth_min','spp_depth_max'),
by.y = c('a_min','a_max')
)
ol[,ol_length := pmin(spp_depth_max,a_max)-pmax(spp_depth_min,a_min)]
ol
为了完整起见,这里是一个使用 non-equi join 而不是调用 foverlaps()
函数来查找重叠的版本。另外,使用OP提供的原始数据,即宽格式activities
library(data.table)
vals <- c("min", "max")
melt(setDT(activities), measure.vars = patterns(vals), variable.name = "activity", value.name = vals)[
setDT(species), on = .(max >= spp_depth_min, min <= spp_depth_max),
.(activity, spp_id, overlap = pmin(x.max, spp_depth_max) - pmax(x.min, spp_depth_min))]
activity spp_id overlap
1: 1 a 50
2: 2 a 70
3: 3 a 200
4: 4 a 200
5: 1 b 30
6: 2 b 50
7: 3 b 180
8: 4 b 480
9: 1 c 20
10: 2 c 20
11: 3 c 20
12: 4 c 20
13: 1 d 10
14: 2 d 30
15: 3 d 60
16: 4 d 60
说明
melt()
用于同时使用多个测量变量将 activities
从宽格式重塑为长格式。
non-equi连接的条件可以通过一些布尔代数导出如下:
两个闭区间[a1,a2]和[b1, b2] 不 重叠 if
b2 < a1 或 a2 < b 1
如果此布尔表达式取反,则两个区间 do 重叠:
NOT( b2 < a1 或 a2 < b1 ) =
NOT( b2 < a1 ) AND NOT( a2 < b 1 ) =
b2 >= a1 AND a2 >= b1
连接标识了所有重叠的间隔对(对于给定的数据集,它们是 4 x 4 = 16 个案例)。每对重叠区域的起点由两个区间中较大的起点给出,终点由两个区间中较小的终点给出。重叠的长度就是极限点之间的差值。
我正在尝试计算海洋物种和人类活动的重叠深度范围。所以对于每个物种,它都有一个最小和最大深度,我想有效地计算与 4 种不同活动的深度范围重叠的深度范围。我认为这可以用 data.table::foverlaps()
或 IRanges::findOverlaps()
来完成,但我不知道如何计算重叠的值,而不仅仅是它是真还是假。因此,如果在 40-100 米深度之间发现物种 D,并且 activity 1 出现在 0-50 米深度,则重叠为 10 米。
例如,
min_1 <- 0
max_1 <- 50
min_2 <- 0
max_2 <- 70
min_3 <- 0
max_3 <- 200
min_4 <- 0
max_4 <- 500
activities <- data.frame(min_1, max_1, min_2, max_2, min_3, max_3, min_4, max_4)
spp_id <- c("a", "b", "c", "d")
spp_depth_min <- c(0, 20, 30, 40)
spp_depth_max <- c(200, 500, 50, 100)
species <- data.frame(spp_id, spp_depth_min, spp_depth_max)
## data.table approach?
setDT(activities)
setDT(species)
foverlaps(species, activities, ...) ## Or do I need to subset each activity and do separate calculations?
写一个函数会不会更简单?我真的很陌生!这似乎应该是一件 common/easy 事情,我不知道为什么它让我如此困惑
我将你的活动 table 重组为一个长表格,这样你就可以一次完成所有 4 项计算。然后overlaps join就完成了,然后就可以根据结果计算出overlap的长度了。
activities <- data.table(
act = c('act_1','act_2','act_3','act_4'),
a_min = c(min_1, min_2, min_3, min_4),
a_max = c(max_1, max_2, max_3, max_4)
)
spp_id <- c("a", "b", "c", "d")
spp_depth_min <- c(0, 20, 30, 40)
spp_depth_max <- c(200, 500, 50, 100)
species <- data.table(spp_id, spp_depth_min, spp_depth_max)
setkey(activities,a_min,a_max)
ol <- foverlaps(species, activities,
by.x = c('spp_depth_min','spp_depth_max'),
by.y = c('a_min','a_max')
)
ol[,ol_length := pmin(spp_depth_max,a_max)-pmax(spp_depth_min,a_min)]
ol
为了完整起见,这里是一个使用 non-equi join 而不是调用 foverlaps()
函数来查找重叠的版本。另外,使用OP提供的原始数据,即宽格式activities
library(data.table)
vals <- c("min", "max")
melt(setDT(activities), measure.vars = patterns(vals), variable.name = "activity", value.name = vals)[
setDT(species), on = .(max >= spp_depth_min, min <= spp_depth_max),
.(activity, spp_id, overlap = pmin(x.max, spp_depth_max) - pmax(x.min, spp_depth_min))]
activity spp_id overlap 1: 1 a 50 2: 2 a 70 3: 3 a 200 4: 4 a 200 5: 1 b 30 6: 2 b 50 7: 3 b 180 8: 4 b 480 9: 1 c 20 10: 2 c 20 11: 3 c 20 12: 4 c 20 13: 1 d 10 14: 2 d 30 15: 3 d 60 16: 4 d 60
说明
melt()
用于同时使用多个测量变量将 activities
从宽格式重塑为长格式。
non-equi连接的条件可以通过一些布尔代数导出如下:
两个闭区间[a1,a2]和[b1, b2] 不 重叠 if
b2 < a1 或 a2 < b 1
如果此布尔表达式取反,则两个区间 do 重叠:
NOT( b2 < a1 或 a2 < b1 ) =
NOT( b2 < a1 ) AND NOT( a2 < b 1 ) =
b2 >= a1 AND a2 >= b1
连接标识了所有重叠的间隔对(对于给定的数据集,它们是 4 x 4 = 16 个案例)。每对重叠区域的起点由两个区间中较大的起点给出,终点由两个区间中较小的终点给出。重叠的长度就是极限点之间的差值。