我有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
Run Code Online (Sandbox Code Playgroud)
如您所见,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
Run Code Online (Sandbox Code Playgroud)
我相信你可以看到,这有两个部分:1.根据一个单独的表将范围分成两列2.在两个部分之间按比例分割#探针
我一直在寻找可以做到这一点的R包(通过染色体臂分开范围),但是找不到如上所示的那个.任何功能包的链接都会受到赞赏,但我也愿意自己编写代码......稍加帮助.
到目前为止,我只能使用foverlaps来确定是否存在重叠:示例:
>foverlaps(Ref.table[data[14]$Chrom], data[14], which=TRUE)
xid yid
1: 1 1
Run Code Online (Sandbox Code Playgroud)
这是一个可能的foverlaps解决方案(如Q中所述).
前两个步骤很简单,非常惯用,添加一个End列,Ref.table所以我们将有重叠的间隔,然后键入两个数据集Chrom和间隔列(在v 1.9.5+,你现在可以指定by.x,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
Run Code Online (Sandbox Code Playgroud)
现在我们有了重叠,我们需要根据匹配增加数据集大小.我们可以对此进行调节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)]
Run Code Online (Sandbox Code Playgroud)
现在,最后两个步骤将根据新列值更新End和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
Run Code Online (Sandbox Code Playgroud)
(如果您愿意,可以删除不需要的列)