我有一个字符串列表(DNA序列),包括A,T,C,G。我想找到所有的匹配并插入到表中,其列是这些DNA字母表的所有可能组合(4 ^ k;" k"是每个匹配的长度 - K-mer - 并且必须由用户指定)和行表示列表中的顺序匹配数。
让我们说我的名单包括5名成员:
DNAlst<-list("CAAACTGATTTT","GATGAAAGTAAAATACCG","ATTATGC","TGGA","CGCGCATCAA")
我想设置k=2
(2-mer),因此可以使用4^2=16
组合,包括AA,AT,AC,AG,TA,TT,...
所以我的表格会有5 rows
和16 columns
。我想计算我的k-mers和列表成员之间的匹配数量。
我想要的结果:df:
lstMemb AA AT AC AG TA TT TC ...
1 2 1 1 0 0 3 0
2 ...
3
4
5
你能帮我在R中实现吗?
答案 0 :(得分:6)
可能有帮助
source("http://bioconductor.org/biocLite.R")
biocLite("Biostrings")
library(Biostrings)
t(sapply(DNAlst, function(x){x1 <- DNAString(x)
oligonucleotideFrequency(x1,2)}))
# AA AC AG AT CA CC CG CT GA GC GG GT TA TC TG TT
#[1,] 2 1 0 1 1 0 0 1 1 0 0 0 0 0 1 3
#[2,] 5 1 1 2 0 1 1 0 2 0 0 1 2 0 1 0
#[3,] 0 0 0 2 0 0 0 0 0 1 0 0 1 0 1 1
#[4,] 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0
#[5,] 1 0 0 1 2 0 2 0 0 2 0 0 0 1 0 0
或者按照@Arun的建议,首先将list
转换为vector
oligonucleotideFrequency(DNAStringSet(unlist(DNAlst)), 2L)
# AA AC AG AT CA CC CG CT GA GC GG GT TA TC TG TT
#[1,] 2 1 0 1 1 0 0 1 1 0 0 0 0 0 1 3
#[2,] 5 1 1 2 0 1 1 0 2 0 0 1 2 0 1 0
#[3,] 0 0 0 2 0 0 0 0 0 1 0 0 1 0 1 1
#[4,] 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0
#[5,] 1 0 0 1 2 0 2 0 0 2 0 0 0 1 0 0
答案 1 :(得分:6)
如果您正在寻找速度,显而易见的解决方案是stringi
包。
计数模式有stri_count_fixed
函数。
现在,检查代码和基准!
DNAlst<-list("CAAACTGATTTT","GATGAAAGTAAAATACCG","ATTATGC","TGGA","CGCGCATCAA")
dna <- stri_paste(rep(c("A","C","G","T"),each=4),c("A","C","G","T"))
result <- t(sapply(DNAlst, stri_count_fixed,pattern=dna,overlap=TRUE))
colnames(result) <- dna
result
AA AC AG AT CA CC CG CT GA GC GG GT TA TC TG TT
[1,] 2 1 0 1 1 0 0 1 1 0 0 0 0 0 1 3
[2,] 5 1 1 2 0 1 1 0 2 0 0 1 2 0 1 0
[3,] 0 0 0 2 0 0 0 0 0 1 0 0 1 0 1 1
[4,] 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0
[5,] 1 0 0 1 2 0 2 0 0 2 0 0 0 1 0 0
fstri <- function(x){
t(sapply(x, stri_count_fixed,dna,T))
}
fbio <- function(x){
t(sapply(x, function(x){x1 <- DNAString(x); oligonucleotideFrequency(x1,2)}))
}
all(fstri(DNAlst)==fbio(DNAlst)) #results are the same
[1] TRUE
longDNA <- sample(DNAlst,100,T)
microbenchmark(fstri(longDNA),fbio(longDNA))
Unit: microseconds
expr min lq mean median uq max neval
fstri(longDNA) 689.378 738.184 825.3014 766.862 793.134 6027.039 100
fbio(longDNA) 118371.825 125552.401 129543.6585 127245.489 129165.711 359335.294 100
127245.489/766.862
## [1] 165.9301
加快了165倍:)
答案 2 :(得分:4)
我的回答并不像@bartektartanus那么快。但是,它也很快,我写了代码......:D
stri_count_fixed
stringi
包可能会变慢
必须为模式生成所有可能的组合,然后,
检查它们在数据中的存在并计算它出现的次数。k
添加值,而不是创建模式字符串。 oligonucleotideFrequency
运行k
在一个大的序列中,该函数冻结了过多的内存使用和
R重新启动,而我的功能运行得非常快。sequence_kmers <- function(sequence, k){
k_mers <- lapply(sequence,function(x){
seq_loop_size <- length(DNAString(x))-k+1
kmers <- sapply(1:seq_loop_size, function(z){
y <- z + k -1
kmer <- substr(x=x, start=z, stop=y)
return(kmer)
})
return(kmers)
})
uniq <- unique(unlist(k_mers))
ind <- t(sapply(k_mers, function(x){
tabulate(match(x, uniq), length(uniq))
}))
colnames(ind) <- uniq
return(ind)
}
我只使用Biostrings
包计算基数......您可以使用stringi
之类的其他选项来计算...
如果您删除k_mers lapply
和return(k_mers)
下面的所有代码,则只返回所有带有相应重复向量的k-me的列表
sequence
这里是一个1000bp #same output for 1 or multiple sequences
> sequence_kmers(sequence,4)[,1:10]
GTCT TCTG CTGA TGAA GAAC AACG ACGC CGCG GCGA CGAG
4 4 3 4 4 8 6 4 5 5
> sequence_kmers(c(sequence,sequence),4)[,1:10]
GTCT TCTG CTGA TGAA GAAC AACG ACGC CGCG GCGA CGAG
[1,] 4 4 3 4 4 8 6 4 5 5
[2,] 4 4 3 4 4 8 6 4 5 5
使用我的功能完成测试:
#super fast for 1 sequence
> system.time({sequence_kmers(sequence,13)})
usuário sistema decorrido
0.08 0.00 0.08
#works fast for 1 sequence or 50 sequences of 1000bps
> system.time({sequence_kmers(rep(sequence,50),4)})
user system elapsed
3.61 0.00 3.61
#same speed for 3-mers or 13-mers
> system.time({sequence_kmers(rep(sequence,50),13)})
user system elapsed
3.63 0.00 3.62
使用Biostrings
进行的测试:
#Slow 1 sequence 12-mers
> system.time({oligonucleotideFrequency(DNAString(sequence),12)})
user system elapsed
150.11 1.14 151.37
#Biostrings package freezes for a single sequence of 13-mers
> system.time({oligonucleotideFrequency(sequence,13)})
freezes, used all my 8gb RAM
答案 3 :(得分:4)
我们最近发布了我们的烤肉串&#39;包装作为Bioconductor的一部分 3.0发布。虽然这个包旨在提供序列内核 用于分类,回归和其他任务,例如基于相似性 集群,该软件包还包括有效计算k-mer频率的功能:
#installing kebabs:
#source("http://bioconductor.org/biocLite.R")
#biocLite(c("kebabs", "Biostrings"))
library(kebabs)
s1 <- DNAString("ATCGATCGATCGATCGATCGATCGACTGACTAGCTAGCTACGATCGACTG")
s1
s2 <- DNAString(paste0(rep(s1, 200), collate=""))
s2
sk13 <- spectrumKernel(k=13, normalized=FALSE)
system.time(kmerFreq <- drop(getExRep(s1, sk13)))
kmerFreq
system.time(kmerFreq <- drop(getExRep(s2, sk13)))
kmerFreq
所以你看到k-mer频率是作为显式获得的 k = 13的标准(非标准化)谱内核的特征向量。 此功能在高效的C ++代码中实现 一个前缀树,只考虑实际出现的k-mers 序列(如您所要求的)。你会看到即使是k = 13和一个序列 有数万个基数,计算只需要几分之一 一秒钟(我们5岁的戴尔服务器上19毫秒)。以上功能 也适用于DNAStringSets,但是,在这种情况下,你应该删除 drop()得到k-mer频率矩阵。矩阵是默认的 稀疏(类&#39; dgRMatrix&#39;),但您也可以强制执行结果 标准的密集矩阵格式(但是,仍然省略了没有的k-mers 在任何序列中都发生了):
sv <- c(DNAStringSet(s1), DNAStringSet(s2))
system.time(kmerFreq <- getExRep(sv, sk13))
kmerFreq
system.time(kmerFreq <- getExRep(sv, sk13, sparse=FALSE))
kmerFreq
k-mers可能有多长,可能取决于您的系统。在我们的系统上, 对于DNA序列,限制似乎是k = 22。对于RNA和RNA也是如此 氨基酸序列。然而,对于后者,k的限制 显着降低,因为特征空间显然很多 相同的k更大。
#for the kebabs documentation please see:
browseVignettes("kebabs")
我希望有所帮助。如果您有任何其他问题,请告诉我。
祝你好运, 乌尔里希
答案 4 :(得分:2)
另一种方法:
DNAlst<-list("CAAACTGATTTT","GATGAAAGTAAAATACCG","ATTATGC","TGGA","CGCGCATCAA","ACACACACACCA")
len <- 4
stri_sub_fun <- function(x) table(stri_sub(x,1:(stri_length(x)-len+1),length = len))
sapply(DNAlst, stri_sub_fun)
[[1]]
AAAC AACT ACTG ATTT CAAA CTGA GATT TGAT TTTT
1 1 1 1 1 1 1 1 1
[[2]]
AAAA AAAG AAAT AAGT AATA ACCG AGTA ATAC ATGA GAAA GATG GTAA TAAA TACC TGAA
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[[3]]
ATGC ATTA TATG TTAT
1 1 1 1
[[4]]
TGGA
1
[[5]]
ATCA CATC CGCA CGCG GCAT GCGC TCAA
1 1 1 1 1 1 1
[[6]]
ACAC ACCA CACA CACC
4 1 3 1