Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-01-21T13:42:47.747Z
Answers.Text: 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.
Answers.UserDisplayName: cmdoret
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-01-21T15:45:04.257Z
Answers.Text: 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)`
Answers.UserDisplayName: cmdoret
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-01-21T17:48:09.507Z
Answers.Text: That a good point. I've added another possibly quicker solution, hope that works!
Answers.UserDisplayName: Sebastian Müller
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-01-21T17:51:06.067Z
Answers.Text: That last solution is a great idea, thanks !
Answers.UserDisplayName: cmdoret
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-01-21T17:53:32.110Z
Answers.Text: If it works for, I'd consolidate the answer since the first iterations are superflous then :)
Answers.UserDisplayName: Sebastian Müller
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-01-21T13:34:56.740Z
Answers.LastActivityDate: 2021-01-23T12:10:49.933Z
Answers.LastEditDate: 2021-01-23T12:10:49.933Z
Answers.UserDisplayName: Sebastian Müller
Body: <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>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2021-01-21T14:36:23.670Z
Comments.Text: Thanks, I just added it
Comments.UserDisplayName: cmdoret
Tags: <r><bioconductor><genomicranges>
Title: Retrieve overlap widths with Bioconductor
ThreadText: # 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:
  
  ```r
  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
        <integer>   <integer>
    [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](https://www.rdocumentation.org/packages/IRanges/versions/2.0.1/topics/setops-methods):
  
  > 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 :)  
  
  ---
  
  