从小的、大小相同的连续箱中重叠和分类计数到不规则、不均匀的箱中

Posted

技术标签:

【中文标题】从小的、大小相同的连续箱中重叠和分类计数到不规则、不均匀的箱中【英文标题】:Overlapping and sorting counts from small, equally sized, continuous bins into irregular, uneven bins 【发布时间】:2022-01-05 06:08:24 【问题描述】:

非常感谢您阅读本文并抽出宝贵的时间帮助我解决我遇到的问题。

在 R 中,我想将数据从一个数据帧中的小而连续的 bin 排序到另一个数据帧中大小和分布不规则的(非重叠)bin,以针对所有重叠间隔。

我的第一个数据框是这样的(实际的数据框有几十万行):

chr         bin    from  to     BS_seq_Count
SL4.0ch01   1      1     500    3
SL4.0ch01   2      501   1000   10  
SL4.0ch01   3      1001  1500   3   
SL4.0ch02   1      1     500    3
SL4.0ch02   2      501   1000   10  
SL4.0ch02   3      1001  1500   3   
SL4.0ch03   1      1     500    3
SL4.0ch03   2      501   1000   10  
SL4.0ch03   3      1001  1500   3
... 

这是我想将其重叠并分类到相应箱中的数据框:

chr         bin    from  to      
SL4.0ch01   1      200   700   
SL4.0ch01   2      800   1300  
SL4.0ch02   1      300   400    
SL4.0ch03   1      50    600
SL4.0ch03   2      700   800    
SL4.0ch03   3      1000  1200
...

最后它应该有点像这样(小数/四舍五入没那么重要,但部分重叠的计数也应该分类到 bin 中):

chr         bin    from  to     count    
SL4.0ch01   1      200   700    5.8
SL4.0ch01   2      800   1350   6.1
SL4.0ch02   1      300   400    0.6
SL4.0ch03   1      50    600    4.7
SL4.0ch03   2      700   800    2
SL4.0ch03   3      1000  1200   1.2
...

我曾想过将 GenomicRanges 与 findOverlaps 函数一起使用,但无法弄清楚在这种情况下如何使其正常工作。

如果有人知道如何解决这个问题,任何帮助将不胜感激!

提前谢谢你,祝你周末愉快,身体健康!

【问题讨论】:

【参考方案1】:

我相当肯定有一种更有效的非 equi 连接方式,但这里有一种使用 data.table 笛卡尔连接的方式:

library(data.table)

dt1 <- setorder(data.table(chr = paste0("SL4.0ch01", rep(1:3, each = 3)), bin = rep(1:3, 3), from = rep(c(1, 501, 1001), 3), to = rep(c(500, 1000, 1500), 3), ct = rep(c(3, 10, 3), 3)), chr)
dt2 <- data.table(chr = paste0("SL4.0ch01", c(1,1,2,3,3,3)), bin = c(1,2,1,1,2,3), from = c(200, 800, 300, 50, 700, 1000), to = c(700, 1350, 400, 600, 800, 1200))
dt3 <- merge.data.table(dt1, dt2, by = "chr", allow.cartesian = TRUE)[, overlap := 0]
dt3[from.x < to.y & from.y < to.x, overlap := ct*(pmin(to.x, to.y) - pmax(from.x, from.y))/(to.x - from.x)]
dt2[, count := dt3[, .(count = sum(overlap)), by = .(chr, bin.y)]$count]
dt2
#>           chr bin from   to     count
#> 1: SL4.0ch011   1  200  700 5.7915832
#> 2: SL4.0ch011   2  800 1350 6.1062124
#> 3: SL4.0ch012   1  300  400 0.6012024
#> 4: SL4.0ch013   1   50  600 4.6893788
#> 5: SL4.0ch013   2  700  800 2.0040080
#> 6: SL4.0ch013   3 1000 1200 1.1963928

【讨论】:

【参考方案2】:

这是一个使用foverlaps() 的解决方案,data.table 版本的IRanges::findOverlaps() 函数:

library(data.table)
foverlaps(dt1, setkey(dt2, chr, from, to), nomatch = NULL)[
  , .(count = sum(BS_seq_Count / (i.to - i.from + 1L) * 
                    (pmin(to, i.to) - pmax(from, i.from) + 1L))), 
  by = .(chr, bin, from, to)]
         chr   bin  from    to count
      <char> <int> <int> <int> <num>
1: SL4.0ch01     1   200   700 5.806
2: SL4.0ch01     2   800  1350 6.120
3: SL4.0ch02     1   300   400 0.606
4: SL4.0ch03     1    50   600 4.706
5: SL4.0ch03     2   700   800 2.020
6: SL4.0ch03     3  1000  1200 1.220

数据

library(data.table)
dt1 <- fread("
chr         bin    from  to     BS_seq_Count
SL4.0ch01   1      1     500    3
SL4.0ch01   2      501   1000   10  
SL4.0ch01   3      1001  1500   3   
SL4.0ch02   1      1     500    3
SL4.0ch02   2      501   1000   10  
SL4.0ch02   3      1001  1500   3   
SL4.0ch03   1      1     500    3
SL4.0ch03   2      501   1000   10  
SL4.0ch03   3      1001  1500   3")
dt2 <- fread("
chr         bin    from  to      
SL4.0ch01   1      200   700   
SL4.0ch01   2      800   1350  
SL4.0ch02   1      300   400    
SL4.0ch03   1      50    600
SL4.0ch03   2      700   800    
SL4.0ch03   3      1000  1200")

【讨论】:

以上是关于从小的、大小相同的连续箱中重叠和分类计数到不规则、不均匀的箱中的主要内容,如果未能解决你的问题,请参考以下文章

多个重叠图的 Seaborn 图例修改

lisp图元计数不准

如何将数据框拆分为与 R 大小相同的元素,由另一个大小重叠,保留每个元素?

SQL:计算每个设备集连续出现相同值的所有记录并返回最高计数

输出 可重叠元素数组的从小到大排列

拖动和调整 div 与另一个 div 重叠