查找 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 个案例)。每对重叠区域的起点由两个区间中较大的起点给出,终点由两个区间中较小的终点给出。重叠的长度就是极限点之间的差值。