我有一个
data.frame
线性间隔(映射RNA序列读取的基因组坐标),例如:
df <- data.frame(seqnames = c(rep("chr10",2),rep("chr5",8)),
start = c(12255935,12257004,12243635,12244009,12253879,12254395,12254506,12255142,12255229,12258719),
end = c(12257002,12258512,12243764,12244291,12254107,12254501,12254515,12255535,12255312,12258764),
read_id = c(rep("R9",2),rep("R10",8)),
stringsAsFactors = F)
对于某些读取,在相同读取的其他读取中包含或相交的间隔,我想合并它们。在上面的例子中
read_id = "R10"
,时间间隔:
chr5 12255229 12255312
被控制在间隔内
chr5 12255142 12255535
.
一读
数据框架
,我使用以下程序:
#defining helper functions
clusterHits <- function(overlap.hits)
{
overlap.hits <- GenomicRanges::union(overlap.hits,t(overlap.hits))
query.hits <- S4Vectors::queryHits(overlap.hits)
search.hits <- S4Vectors::subjectHits(overlap.hits)
cluster.ids <- seq_len(S4Vectors::queryLength(overlap.hits))
while(TRUE){
hit <- S4Vectors::Hits(query.hits,cluster.ids[search.hits],S4Vectors::queryLength(overlap.hits),S4Vectors::subjectLength(overlap.hits))
tmp.cluster.ids <- pmin(cluster.ids,S4Vectors::selectHits(hit,"first"))
if(identical(tmp.cluster.ids,cluster.ids))
break
cluster.ids <- tmp.cluster.ids
}
unname(S4Vectors::splitAsList(seq_len(S4Vectors::queryLength(overlap.hits)),cluster.ids))
}
mergeConnectedRanges <- function(x.gr,overlap.hits)
{
cluster.ids <- clusterHits(overlap.hits)
merged.gr <- range(IRanges::extractList(x.gr,cluster.ids))
merged.gr <- unlist(merged.gr)
S4Vectors::mcols(merged.gr)$merged.idx <- cluster.ids
return(merged.gr)
}
#Now separate R10 and merge its intervals
df1 <- dplyr::filter(df, read_id == "R10")
gr <- GenomicRanges::GRanges(dplyr::select(df1,seqnames,start,end))
redundant.intervals <- GenomicRanges::findOverlaps(gr,ignore.strand=T)
query.gr <- redundant.intervals[S4Vectors::queryHits(redundant.intervals)]
subject.gr <- redundant.intervals[S4Vectors::subjectHits(redundant.intervals)]
as.data.frame(mergeConnectedRanges(x.gr=gr,overlap.hits=redundant.intervals))
它给出:
seqnames start end width strand merged.idx
1 chr5 12243635 12243764 130 * 1
2 chr5 12244009 12244291 283 * 2
3 chr5 12253879 12254107 229 * 3
4 chr5 12254395 12254501 107 * 4
5 chr5 12254506 12254515 10 * 5
6 chr5 12255142 12255535 394 * 6, 7
7 chr5 12258719 12258764 46 * 8
所以
merged.idx
显示间隔6和7英寸
df1
已经合并。
我正在寻找一种跨越数千次阅读的快速方法。显而易见的方法是使用
do.call
穿过独特的阅读区
df
:
library(dplyr)
do.call(rbind, lapply(unique(df$read_id), function(r){
read.df <- dplyr::filter(df, read_id == r)
gr <- GenomicRanges::GRanges(dplyr::select(read.df,seqnames,start,end))
redundant.intervals <- GenomicRanges::findOverlaps(gr,ignore.strand=T)
query.gr <- redundant.intervals[S4Vectors::queryHits(redundant.intervals)]
subject.gr <- redundant.intervals[S4Vectors::subjectHits(redundant.intervals)]
as.data.frame(mergeConnectedRanges(x.gr=gr,overlap.hits=redundant.intervals)) %>%
dplyr::mutate(read_id = r)
}))