我想在包含一些标签的BAM文件中阅读,然后将其转换为pip install pycomm
以进行进一步处理。
一般来说,这可以很简单地实现:
tibble
library(Rsamtools)
library(tidyverse)
map.info <- c("rname", "strand", "pos")
map.params <- ScanBamParam(what = map.info)
bam <- scanBam(bam.file, param = map.params)
会返回一个包含命名向量scanBam
,rname
和strand
的列表,可以使用pos
轻松加入。但是,假设我对dplyr::bind_cols(bam)
- 标签感兴趣,我需要执行以下操作:
MD
现在,map.params <- ScanBamParam(what = map.info, tag = c("MD"))
bam <- scanBam(bam.file, param = map.params)
是一个列表列表,其中包含命名向量bam
,rname
和strand
,但另一个pos
本身也是如此一个列表,其中一个名为vector tag
。
MD
无法处理此嵌套列表列表,并引发错误,但dplyr::bind_cols
有效。
一个充满了问题的玩具示例:
as.data.frame(bam)
有没有办法在嵌套列表中递归> df.list <- list(a = 1:2, b = 3:4, c = 5:6)
> df.nest <- list(a = 1:2, b = 3:4, c = 5:6, d = list( e = 7:8 ))
> dplyr::bind_cols(df.list)
# A tibble: 2 x 3
a b c
<int> <int> <int>
1 1 3 5
2 2 4 6
> dplyr::bind_cols(df.nest)
Error in cbind_all(x) : Argument 4 must be length 2, not 1
> as.data.frame(df.nest)
a b c e
1 1 3 5 7
2 2 4 6 8
?
受到@ mt1022答案的启发,并且没有进一步检查bind_cols
基本代码,似乎尽管格式与玩具示例非常相似,但Rsamtools
输出的行为并不像玩具示例。
但是,正如我们所知道的那样,以下内容也应该实现完全合并scanBam
:
tibble
它似乎比我希望的(或预期的)更加晦涩,但它确实有效。
有三个选项可以产生类似的结果:
map.info <- c("rname", "strand", "pos")
map.params <- ScanBamParam(what = map.info, tag = c("MD", "NM"))
bam <- scanBam(bam.file, param = map.params)
bam.tbl <- bind_cols(do.call(bind_cols, bam[[1]][c("rname", "strand", "pos")]),
do.call(bind_cols, bam[[1]]$tag))
as.data.frame(bam)
bind_cols(do.call(bind_cols, bam[[1]][map.info]), do.call(bind_cols, bam[[1]]$tag))
我认为一个带有bind_cols(lapply(bam, as.data.frame), .id = 'rn')
行的示例bam文件应该可以很好地了解哪种方法最快。
10762160
as&#39; clunky&#39;看起来,我想对> length(bam[[1]]$rname)
[1] 10762160
> system.time(for (i in 1:100) as.data.frame(bam))
user system elapsed
70.565 25.821 96.699
> system.time(for (i in 1:100) bind_cols(do.call(bind_cols, bam[[1]][mapI]), do.call(bind_cols, bam[[1]]$tag)))
user system elapsed
0.124 0.020 0.144
> system.time(for (i in 1:100) dplyr::bind_rows(lapply(bam, as.data.frame), .id = 'rn'))
user system elapsed
108.091 36.046 144.623
的嵌套调用是最快的!
答案 0 :(得分:0)
受bind_cols
手册中的这个例子的启发:
# You can mix vectors and data frames:
bind_rows(
c(a = 1, b = 2),
data_frame(a = 3:4, b = 5:6),
c(a = 7, b = 8)
)
我想我们可以尝试:
do.call(bind_cols, df.nest)
# # A tibble: 2 x 4
# a b c e
# <int> <int> <int> <int>
# 1 1 3 5 7
# 2 2 4 6 8
library(Rsamtools)
# generate sample data using internal bam file of Rsamtools
which <- RangesList(seq1=IRanges(1000, 2000),
seq2=IRanges(c(100, 1000), c(1000, 2000)))
what <- c("rname", "strand", "pos")
param <- ScanBamParam(which=which, what=what, tag = c("NM"))
bamFile <- system.file("extdata", "ex1.bam", package="Rsamtools")
bam <- scanBam(bamFile, param=param)
# convert bam to a data.frame
bam.df <- dplyr::bind_rows(lapply(bam, as.data.frame), .id = 'rn')
# rn rname strand pos NM
# 1 seq1:1000-2000 seq1 + 970 0
# 2 seq1:1000-2000 seq1 + 971 0
# 3 seq1:1000-2000 seq1 + 972 0
# ......