范围重叠/按组和年份之间交叉

时间:2015-01-19 06:49:52

标签: r range overlap intersect

我有一个标记个人列表(列标记),这些列表已在河流范围内(LocStart和LocEnd)捕获了不同年份(列年份)。河上的位置以米为单位。

我想知道一个有标记的人是否使用了多年的重叠范围,即个人是否每年都去过同一段河流。

以下是原始数据集的示例:

  

ID 标记 LocStart LocEnd
   1 {1081 {1}} {1992年{1}} {21729 {1}} 22229
   2 {1081 {1}} {1992年{1}} {21203 {1}} 21703
   3 {1081 {1}} {2005 {1}} {21508 {1}} 22008
   4 {1126 {1}} {1994年{1}} {19222 {1}} 19522
   5 {1126 {1}} {1994年{1}} {18811 {1}} 19311
   6 {1283 {1}} {2005 {1}} {21754 {1}} 22254
   7 1283 2007 22,025 22,525

以下是我想要的最终答案:

  

标记 {YEAR1 {1}} {YEAR2 {1}}的ID
  1081 1992 2005 1,3   1081 1992 2005 2,3   1283 2005 2007 6,7

在这种情况下,个别1126不会出现在最终输出中,因为可用的唯一两个范围是同一年。我意识到删除Year1 = Year2的所有记录都很容易。

我想在R中执行此操作,并查看了> IRanges包,但未能考虑group = Mark并且能够提取Year1和Year2信息。

1 个答案:

答案 0 :(得分:6)

使用foverlaps()包中的data.table函数:

require(data.table)
setkey(setDT(dt), Mark, LocStart, LocEnd)               ## (1)
olaps = foverlaps(dt, dt, type="any", which=TRUE)       ## (2)
olaps = olaps[dt$Year[xid] != dt$Year[yid]]             ## (3)
olaps[, `:=`(Mark  = dt$Mark[xid], 
             Year1 = dt$Year[xid],
             Year2 = dt$Year[yid],
             xid   = dt$ID[xid], 
             yid   = dt$ID[yid])]                       ## (4)
olaps = olaps[xid < yid]                                ## (5)
#    xid yid Mark Year1 Year2
# 1:   2   3 1081  1992  2005
# 2:   1   3 1081  1992  2005
# 3:   6   7 1283  2005  2007
  1. 我们首先使用setDT通过引用将 data.frame 转换为 data.table 。然后,我们MarkLocStartLocEnd上的 data.table ,这将允许我们执行重叠范围联接。

  2. 我们使用任何类型的重叠来计算自身重叠dt自身)。但我们使用which = TRUE返回匹配的索引。

  3. 删除与Yearxid对应的yid相同的所有索引。

  4. 添加所有其他列,并通过引用将xidyid替换为相应的ID值。

  5. 删除xid&gt; = yid的所有索引。如果第1行与第3行重叠,则第3行也与第1行重叠。我们不需要两者。 foverlaps()默认情况下还没有办法将其删除。