我正试图计算海洋物种和人类活动的重叠深度范围。因此,对于每个物种,都有一个最小和最大深度,我想有效地计算与4种不同活动的深度范围重叠的深度范围。我认为这可以用data.table::foverlaps()
或IRanges::findOverlaps()
来完成,但我不知道如何计算重叠的值,而不仅仅是它是真是假。因此,如果物种D在40-100米深度之间发现,而活动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?
编写函数会更容易吗?我真的不熟悉!这似乎应该是一件常见/容易的事情,我不知道为什么它让我如此困惑
我将活动表重新构造为一个长表单,这样您就可以一次完成所有4个计算。然后完成重叠连接,然后可以根据结果计算重叠长度。
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
为了完整起见,这里有一个版本使用非等联接,而不是调用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
从宽格式重塑为长格式,同时具有多个度量变量。
非等连接的条件可以由一些布尔代数导出如下:
如果,两个闭合区间[a1,a2]和[b1,b2]是否重叠
b2<a1或a2<b1
如果该布尔表达式被否定,则的两个区间重叠:
NOT(b2<a1或a2lt;b1(=
NOT(b2<a1(AND NOT(a2<b1(=
b2>=a1与a2>=b1
连接标识所有重叠的区间对(对于给定的数据集为4 x 4=16种情况(。每对重叠区域的起点由两个区间中较大的起点给出,终点由两个间隔中较小的终点给出。重叠的长度是极限点之间的差值。