R - 将数据框行拆分为两行

2024-01-12

我有 2 个表(数据和参考;下面的玩具示例)。这些表有 START 和 END 位置,我想检查它们是否重叠(使用 data.table 包中的 foverlaps 之类的东西),然后拆分值,如下所示。

>data  <- data.table(ID=c(1,2,3), Chrom=c(1,1,2), Start=c(1,500,1000), End=c(900,5000,5000), Probes=c(899,4500,4500))
>Ref.table <- data.table(Chrom=c(1,2), Split=c(1000,2000))

>Ref.table
Chrom    Split
1        1000
2        2000

>data
ID    Chrom    Start    End    Probes
1     1        1        900    899
2     1        500      5000   4500
3     2        1000     5000   4000

正如您所看到的,ID 1 与引用表没有重叠,因此它将被保留。但是,ID 2 和 3,我想根据 Ref.table 进行拆分。

我想要得到的结果表是:

>result
ID    Chrom    Start    End    Probes
1     1        1        900    899
2     1        500      1000   500
2     1        1001     5000   4000
3     2        1000     2000   1000
3     2        2001     5000   3000

我相信您可以看到,这有两个部分: 1. 根据单独的表将范围拆分为两列 2. 按比例将 # 个探针分成两部分

我一直在寻找一个可以做到这一点的 R 包(通过染色体臂分割范围),但一直无法找到一个可以实现如上所示的功能的包。任何指向函数包的链接将不胜感激,但我也愿意自己编写代码......在一点帮助下。

到目前为止,我只能使用 foverlaps 来确定是否存在重叠: 例子:

>foverlaps(Ref.table[data[14]$Chrom], data[14], which=TRUE)
     xid   yid
1:    1     1

这是一个可能的foverlaps解决方案(如Q中所述)。

前两个步骤很简单并且非常惯用,添加一个End列至Ref.table所以我们会有重叠的间隔,然后将两个数据集键入Chrom和间隔列(在 v 1.9.5+ 中,您现在可以指定by.x and by.y相反)并简单地运行foverlaps

library(data.table)
setDT(Ref.table)[, End := Split]
setkey(Ref.table)
setkey(setDT(data), Chrom, Start, End)
res <- foverlaps(data, Ref.table)
res
#    Chrom Split  End ID Start i.End Probes
# 1:     1    NA   NA  1     1   900    899
# 2:     1  1000 1000  2   500  5000   4500
# 3:     2  2000 2000  3  1000  5000   4000

现在我们有了重叠,我们需要根据匹配增加数据集大小。我们可以将其作为条件is.na(Split)(这意味着没有发现重叠)。我不确定这部分是否可以更有效地完成

res2 <- res[, if(is.na(Split)) .SD else rbind(.SD, .SD), by = .(ID, Chrom)]
## Or, if you only have one row per group, maybe
## res2 <- res[, if(is.na(Split)) .SD else .SD[c(1L,1L)], by = .(ID, Chrom)]

现在,最后两个步骤将更新End and Start列,然后是Probes根据新列值的列

res2[!is.na(Split), `:=`(i.End = c(Split[1L], i.End[-1L]),
                         Start = c(Start[-1L], Split[1L] + 1L)), 
     by = .(ID, Chrom)]
res2[!is.na(Split), Probes := i.End - Start]
res2
#    ID Chrom Split  End Start i.End Probes
# 1:  1     1    NA   NA     1   900    899
# 2:  2     1  1000 1000   500  1000    500
# 3:  2     1  1000 1000  1001  5000   3999
# 4:  3     2  2000 2000  1000  2000   1000
# 5:  3     2  2000 2000  2001  5000   2999

(如果您愿意,可以删除不需要的列)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

R - 将数据框行拆分为两行 的相关文章

随机推荐