我有两个data.frames,每个都有三列:chrom,start和stop,让我们称它们为rangesA和rangesB.对于每行rangeA,我想找到rangeB中哪一行(如果有的话)完全包含rangesA行 - 我的意思是rangesAChrom == rangesBChrom, rangesAStart >= rangesBStart and rangesAStop <= rangesBStop.
现在我正在做以下,我不太喜欢.请注意,由于其他原因,我正在循环遍历rangeA的行,但这些原因都不是什么大问题,它最终会让这些特定解决方案更具可读性.
rangesA:
chrom start stop
5 100 105
1 200 250
9 275 300
Run Code Online (Sandbox Code Playgroud)
rangesB:
chrom start stop
1 200 265
5 99 106
9 275 290
Run Code Online (Sandbox Code Playgroud)
对于范围A中的每一行:
matches <- which((rangesB[,'chrom'] == rangesA[row,'chrom']) &&
(rangesB[,'start'] <= rangesA[row, 'start']) &&
(rangesB[,'stop'] >= rangesA[row, 'stop']))
Run Code Online (Sandbox Code Playgroud)
我认为必须有一个更好的(并且更好,我的意思是比大范围A和rangeB的大型实例更快)这样做的方式比循环这个结构.有任何想法吗?
Aar*_*ham 20
使用Bioconductor提供的IRanges/GenomicRanges包装,用于处理这些确切的问题(并大规模扩展)
source("http://bioconductor.org/biocLite.R")
biocLite("IRanges")
Run Code Online (Sandbox Code Playgroud)
在不同的染色体上有一些适用于范围的容器,一个是RangesList
library(IRanges)
rangesA <- split(IRanges(rangesA$start, rangesA$stop), rangesA$chrom)
rangesB <- split(IRanges(rangesB$start, rangesB$stop), rangesB$chrom)
#which rangesB wholly contain at least one rangesA?
ov <- countOverlaps(rangesB, rangesA, type="within")>0
Run Code Online (Sandbox Code Playgroud)
Jos*_*ich 13
如果您可以先合并这两个对象,这将更容易/更快.
ranges <- merge(rangesA,rangesB,by="chrom",suffixes=c("A","B"))
ranges[with(ranges, startB <= startA & stopB >= stopA),]
# chrom startA stopA startB stopB
#1 1 200 250 200 265
#2 5 100 105 99 106
Run Code Online (Sandbox Code Playgroud)
Aru*_*run 12
该data.table软件包具有一个foverlaps()能够在v1.9.4之后合并区间范围的功能:
require(data.table)
setDT(rangesA)
setDT(rangesB)
setkey(rangesB)
foverlaps(rangesA, rangesB, type="within", nomatch=0L)
# chrom start stop i.start i.stop
# 1: 5 99 106 100 105
# 2: 1 200 265 200 250
Run Code Online (Sandbox Code Playgroud)
setDT() 通过引用将data.frame转换为data.table
setkey() 通过提供的列对data.table进行排序(在本例中为所有列,因为我们没有提供任何列),并将这些列标记为已排序,我们稍后将使用它们来执行连接.
foverlaps()重叠连接是否有效.有关详细说明和与其他方法的比较,请参阅此答案.
RangesA 和 RangesB 显然是 BED 语法,这可以在 R 之外的命令行中使用 BEDtools 完成,非常快速且灵活,并具有十几个其他选项来处理基因组间隔。然后将结果再次放入 R 中。
https://code.google.com/p/bedtools/
我添加dplyr解决方案。
library(dplyr)
inner_join(rangesA, rangesB, by="chrom") %>%
filter(start.y < start.x | stop.y > stop.x)
Run Code Online (Sandbox Code Playgroud)
输出:
chrom start.x stop.x start.y stop.y
1 5 100 105 99 106
2 1 200 250 200 265
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18887 次 |
| 最近记录: |