<p>Whilst <code>intersect</code> is sort of doing what you want, it merges adjacent overlaps together which is not what you want I suppose. There doesn't seem to be dedicated <code>Grange</code> function to do this out of the box, but you could go through all overlapping pairs resulting from <code>findOverlap</code> and calculate it's widths using <a href="https://www.rdocumentation.org/packages/IRanges/versions/2.0.1/topics/setops-methods" rel="nofollow noreferrer">pintersect</a>:</p>
<blockquote>
<p>punion, pintersect, psetdiff and pgap are generic functions that compute the element-wise (aka &quot;parallel&quot;) union, intersection, (asymmetric!) difference and gap between each element in x and its corresponding element in y.</p>
</blockquote>
<blockquote>
<p>&quot;pintersect&quot;(x, y, resolve.empty=c(&quot;none&quot;, &quot;max.start&quot;, &quot;start.x&quot;), ...) # x, y   IRanges objects.</p>
</blockquote>
<pre><code>hits &lt;- findOverlaps(gr1, gr2)

width(pintersect(gr1[queryHits(hits)],
                 gr2[subjectHits(hits)]))
[1]  2  6  4  6 10
</code></pre>

CC BY-SA 4.0
2021-01-21T13:42:47.747Z
If I understand correctly, `pintersect` only computes the intersection between pairs of ranges at the same position. (e.g. 2nd vs 2nd). This implies you have the same number of ranges in `gr1` and `gr2`. I am interested in the all-vs-all intersection. I will update my example to make that clearer, sorry.
cmdoret
CC BY-SA 4.0
2021-01-21T15:45:04.257Z
Thanks that answers the question :) The only issue is that the R loop is super slow. In my case I have 468,000 intersections and it's still running after 10mins. I have found an alternative which runs in 0.1 sec, but it is imperfect as I have to truncate intervals by 1bp (slightly wrong results):

`mywidths <- width(intersect(narrow(gr1, start=2), narrow(gr2, start=2))); comp_df <- data.frame(feat1 = ol@from, feat2 = ol@to, size = mywidths)`
cmdoret
CC BY-SA 4.0
2021-01-21T17:48:09.507Z
That a good point. I've added another possibly quicker solution, hope that works!
Sebastian Müller
CC BY-SA 4.0
2021-01-21T17:51:06.067Z
That last solution is a great idea, thanks !
cmdoret
CC BY-SA 4.0
2021-01-21T17:53:32.110Z
If it works for, I'd consolidate the answer since the first iterations are superflous then :)
Sebastian Müller
CC BY-SA 4.0
2021-01-21T13:34:56.740Z
2021-01-23T12:10:49.933Z
2021-01-23T12:10:49.933Z
Sebastian Müller
<p>I want to retrieve all overlaps between two sets of genomic intervals (GRanges) using Bioconductor. I am interested in the widths of the resulting overlapping ranges.</p>
<p>In cases with discontinuous ranges, <code>intersect()</code> works, but I am interested in the case where both sets contain contiguous ranges (no gaps).</p>
<p>I am using the findOverlaps function as in the example below:</p>
<pre class="lang-r prettyprint-override"><code>gr1 &lt;- GRanges(seqnames=&quot;chr2&quot;, ranges=IRanges(c(1, 11, 21, 31), c(10, 20, 30, 40)))
gr2 &lt;- GRanges(seqnames=&quot;chr2&quot;, ranges=IRanges(c(1, 5, 15), c(4, 14, 30)))
hits &lt;- findOverlaps(gr1, gr2)
</code></pre>
<p>This code yields the following intersections in a &quot;Hits&quot; object:</p>
<pre><code>Hits object with 5 hits and 0 metadata columns:
      queryHits subjectHits
      &lt;integer&gt;   &lt;integer&gt;
  [1]         1           1
  [2]         1           2
  [3]         2           2
  [4]         2           3
  [5]         3           3
  -------
  queryLength: 4 / subjectLength: 3
</code></pre>
<p>But I could not find a way to extract the intersections widths from the resulting object.</p>
<p>It this the wrong approach ?</p>
<blockquote>
<p>Note: Using <code>intersect(gr1, gr2)</code> in this case yields a single contiguous overlap range spanning the whole chromosome, but I want each overlap to be returned independently, just like findOverlaps does.</p>
</blockquote>

CC BY-SA 4.0
2021-01-21T14:36:23.670Z
Thanks, I just added it
cmdoret
<r><bioconductor><genomicranges>
Retrieve overlap widths with Bioconductor
# Retrieve overlap widths with Bioconductor

(Asked by: username_0 on 2021-01-21)

I want to retrieve all overlaps between two sets of genomic intervals (GRanges) using Bioconductor. I am interested in the widths of the resulting overlapping ranges.
In cases with discontinuous ranges, intersect() works, but I am interested in the case where both sets contain contiguous ranges (no gaps).
I am using the findOverlaps function as in the example below:
gr1 <- GRanges(seqnames="chr2", ranges=IRanges(c(1, 11, 21, 31), c(10, 20, 30, 40)))
gr2 <- GRanges(seqnames="chr2", ranges=IRanges(c(1, 5, 15), c(4, 14, 30)))
hits <- findOverlaps(gr1, gr2)

This code yields the following intersections in a "Hits" object:
Hits object with 5 hits and 0 metadata columns:
      queryHits subjectHits
         
  [1]         1           1
  [2]         1           2
  [3]         2           2
  [4]         2           3
  [5]         3           3
  -------
  queryLength: 4 / subjectLength: 3

But I could not find a way to extract the intersections widths from the resulting object.
It this the wrong approach ?

Note: Using intersect(gr1, gr2) in this case yields a single contiguous overlap range spanning the whole chromosome, but I want each overlap to be returned independently, just like findOverlaps does.

**Tags:** r, bioconductor, genomicranges
> **Comments:**
> **username_0**: Thanks, I just added it  

---

## 1 answers

### Answer by username_1 on 2021-01-21. Score: 1 | Accepted answer

Whilst intersect is sort of doing what you want, it merges adjacent overlaps together which is not what you want I suppose. There doesn't seem to be dedicated Grange function to do this out of the box, but you could go through all overlapping pairs resulting from findOverlap and calculate it's widths using pintersect:

punion, pintersect, psetdiff and pgap are generic functions that compute the element-wise (aka "parallel") union, intersection, (asymmetric!) difference and gap between each element in x and its corresponding element in y.


"pintersect"(x, y, resolve.empty=c("none", "max.start", "start.x"), ...) # x, y   IRanges objects.

hits <- findOverlaps(gr1, gr2)

width(pintersect(gr1[queryHits(hits)],
                 gr2[subjectHits(hits)]))
[1]  2  6  4  6 10

> **Comments:**
> **username_0**: If I understand correctly, `pintersect` only computes the intersection between pairs of ranges at the same position. (e.g. 2nd vs 2nd). This implies you have the same number of ranges in `gr1` and `gr2`. I am interested in the all-vs-all intersection. I will update my example to make that clearer, sorry.  
> **username_0**: Thanks that answers the question :) The only issue is that the R loop is super slow. In my case I have 468,000 intersections and it's still running after 10mins. I have found an alternative which runs in 0.1 sec, but it is imperfect as I have to truncate intervals by 1bp (slightly wrong results):  `mywidths <- width(intersect(narrow(gr1, start=2), narrow(gr2, start=2))); comp_df <- data.frame(feat1 = ol@from, feat2 = ol@to, size = mywidths)`  
> **username_1**: That a good point. I've added another possibly quicker solution, hope that works!  
> **username_0**: That last solution is a great idea, thanks !  
> **username_1**: If it works for, I'd consolidate the answer since the first iterations are superflous then :)  

---

