R中的子集SAM / BAM文件

时间:2014-06-13 12:52:58

标签: r subset bioinformatics bioconductor

我有一个包含大量读取的BAM文件。 我可以使用scanBam中的Rsamtools将其加载到R中。

但是,我只需要读取子集。 我有一个character向量,其中包含我感兴趣的qnames。

scanBam返回一个包含1个元素的列表,该列表包含13个元素,其中包含所有数千个读取的数据。

如何通过qname保留结构来对此对象进行子集化? 我无法在手册或网上找到任何内容。

2 个答案:

答案 0 :(得分:1)

使用GenomicAlignments :: readGAlignments输入数据可能更方便,包括通过指定param = ScanBamParam(what =" qname")作为参数的qname。然后,您可以使用%in%进行子集化。这是一个更完整的示例,使用其中一个ExperimentData

library(GenomicAlignments)
library(RNAseqData.HNRNPC.bam.chr14)

fname <- RNAseqData.HNRNPC.bam.chr14_BAMFILES[1]    
want <- c("ERR127306.11930623", "ERR127306.24720935",
    "ERR127306.23706011", "ERR127306.22418829", "ERR127306.13372247",
    "ERR127306.20686334", "ERR127306.11412145", "ERR127306.4711647",
    "ERR127306.7479582", "ERR127306.12737243")
aln <- readGAlignments(fname, param=ScanBamParam(what="qname"))
aln[mcols(aln)$qname %in% want]

BAM文件当然很大,而qnames是其中很重要的一部分;以块的形式迭代文件通常是有意义的。这是使用yieldReduce启用(在当前的Rsamtools中),其中一个为BamFile提供yieldSize设置为合理(例如,1M)的读取数量,MAP函数输入一大块数据并处理它(例如,过滤不需要的读取),一个(可选的)REDUCE函数用于连接结果,一个(可选的)DONE函数用于指示迭代何时完成。解决方案看起来像(yieldSize人为地小,允许用样本数据进行说明):

bfl <- BamFile(fname, yieldSize=100000)  ## larger, e.g., 1M-5M
MAP <- function(bfl, want) {
    ## message("tick")
    aln <- readGAlignments(bfl, param=ScanBamParam(what="qname"))
    if (length(aln) == 0)
        NA                          # semaphore -- DONE
    else
        aln[mcols(aln)$qname %in% want]
}
REDUCE <- c
DONE <- function(x) identical(x, NA)
result <- yieldReduce(bfl, MAP, REDUCE, DONE, want=want)

可以采用类似的方法使用scanBam,但数据结构(列表列表)处理起来比较复杂:

x <- scanBam(fname, param=ScanBamParam(what=c("qname", "pos")))
keep <- lapply(lapply(x, "[[", "qname"), "%in%", want)
result <- Map(function(elts, keep) {
    lapply(elts, "[", keep)
}, x, keep)

这也可以与yieldReduce一起使用。

如果您对使用已过滤的读取创建 bam文件感兴趣,那么

filter_factory <- function(want) {
    list(KeepQname = function(x) x$qname %in% want)
}
filter <- FilterRules(filter_factory(want))
dest <- filterBam(fname, tempfile(), filter=filter,
                  param=ScanBamParam(what="qname"))
readGAlignments(dest)

答案 1 :(得分:1)

我最终使用subset(DataFrame(scanBam(bam_file)[[1]]),qname %in% qname_vector)。 这并不保持完全相同的结构(列表清单),但所有信息都保存并且易于访问。