1

如果您正在阅读本文并花宝贵的时间帮助我解决我遇到的问题,我真的很感激。

在 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
...

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

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 函数一起使用,但无法弄清楚在这种情况下如何使其正常工作。

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

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

4

2 回答 2

0

这是一个使用函数foverlaps()版本的 解决方案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")
于 2021-12-28T01:14:15.273 回答
0

我相当肯定有一种更有效的非 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
于 2021-11-29T22:19:36.190 回答