R,如果一个表中的数字属于另一个表中的范围

时间:2014-12-23 15:03:16

标签: r

我有两张桌子。第一个看起来像:

V1 V2
128 1.0000  
139 0.9375
141 1.0000

第二个看起来像:

V1 V2 V3
gene    90  100
mRNA    120 129
CDS 130 139
CDS 140 150

第二个表中的V2和V3是范围的边界(例如90:100,120:129等) 所以我需要比较1表中V1的数字,如果它属于任何范围。如果是这样,我需要将这些行组合在一起。 所以它看起来像

V1.1 V2.1 V1.2 V2.2 V3.2
128 1.0000 mRNA 120 129
139 0.9375 CDS 130 139
141 1.0000 CDS 140 150

或者smth。

问题是这些表格非常大(每个约5G)。

提前谢谢。

2 个答案:

答案 0 :(得分:3)

考虑到数据集的大小,我建议foverlaps包中的data.table

library(data.table)
##
setDT(d1)
setDT(d2)
##
setnames(d2,c("V1.y","V2.y","V3.y"))
setkeyv(d2,c("V2.y","V3.y"))
##
setnames(d1,c("V1.x","V2.x"))
d1[,V11:=V1.x]
##
Merged <- foverlaps(
  x=d1,y=d2,
  by.x=c("V1.x","V11"),
  type="within")
Merged[,V11:=NULL]
##
R> Merged
   V1.y V2.y V3.y V1.x   V2.x
1: mRNA  120  129  128 1.0000
2:  CDS  130  139  139 0.9375
3:  CDS  140  150  141 1.0000

我附加.x.y只是为了清楚起见。 foverlaps主要用于连接两个范围,每个表中使用一个范围,因此它要求by.x指定x对象中的两个(不同)列。我知道在这种情况下解决这个问题的唯一方法就是创建一个临时的重复列,我希望x的一列在y的两列范围内。这是d1[,V11:=V1.x]的目的;之后被删除。

数据:

d1 <- read.table(
  text="V1 V2
128 1.0000  
139 0.9375
141 1.0000",
  header=TRUE)
d2 <- read.table(
  text="V1 V2 V3
gene    90  100
mRNA    120 129
  CDS 130 139
  CDS 140 150",
  header=TRUE)

答案 1 :(得分:1)

就我个人而言,我不会在R中这样做,尽管可能有一种像GRanges这样的生物传导器包。相反,我会将文件转换为BED format,对它们进行排序(使用sort -k1,1 -k2,2n)并使用bedtools intersect,例如

intersectBed -a tbl1.bed -b tbl2.bed -wa -wb -sorted > merged.bed