如何比较数据帧1的每一行与数据帧2的每一行?

时间:2014-11-20 19:31:56

标签: r dataframe data.table

我有两个看起来像这样的数据框:

x=data.frame(Name=c("200003","200260","400826","400863","500710"),Chr=c("chr1","chr1","chr2","chr3","chr3"),Position=c(11880,14415,13000,15000,18000))    
y=data.frame(name=c("geneA","geneB","geneC","geneD","geneE"),chrom=c("chr1","chr1","chr2","chr2","chr3"),Start=c(11873,11878,12000,14361,14361),End=c(14409,14419,14409,16765,19759))

> x
    Name  Chr Position
1 200003 chr1    11880
2 200260 chr1    14415
3 400826 chr2    13000
4 400863 chr3    15000
5 500710 chr3    18000

> y
   name chrom   Start   End
1 geneA  chr1   11873 14409
2 geneB  chr1   11878 14419
3 geneC  chr2   12000 14409
4 geneD  chr2   14361 16765
5 geneE  chr3   14361 19759

我想比较x和y,并返回一个数据帧或列表,其中包含x中每个Name以及与Chr具有相同chrom的y的名称,并且(Start,End)间隔包括Position。例如,

200003  geneA
200003  geneB
200260  geneB
400826  geneC
400863  geneE
500710  geneE

编辑:我能够使用以下代码获得结果

z=merge(x,y,by.x='Chr',by.y='chrom')
z=cbind(z,with(z, Position>=Start & Position<=End))
z=z[-which(z[,7]=="FALSE"),]
output=cbind(as.character(z$Name),as.character(z$name))

实际上x和y以及大型数据集,merge运行需要一段时间。有更好的方法吗?

2 个答案:

答案 0 :(得分:4)

@BondedDust似乎已经删除了他的解决方案。他的解决方案唯一的问题是关键还需要包括chrom

此处使用foverlaps中的data.table。首先,我们将data.frames转换为data.tables:

require(data.table)
setDT(x)
setDT(y)

然后,由于foverlaps适用于区间范围,我们将为x添加一个虚拟列,如下所示:

x[, Position2 := Position]

现在,对于每个x,我们想知道Chr, Position, Position2是否完全 <{1}} y chrome,Start,End y 1}}。我们将setkey(y, chrom, Start, End) foverlaps(x, y, by.x=c("Chr", "Position", "Position2"))[, list(Name, name)] # Name name # 1: 200003 geneA # 2: 200003 geneB # 3: 200260 geneB # 4: 400826 geneC # 5: 400863 geneE # 6: 500710 geneE 用作&#34; key&#34;如下:

{{1}}

data.frames中的列具有异常名称和外壳 - &#34; chrom&#34; vs&#34; Chr&#34;。使用一致的名称可能更容易。

答案 1 :(得分:2)

这或多或少地提供了你想要的东西(它不是粗糙的,如果有多个匹配,x的名称会重复):

library(sqldf)
sqldf("select x.Name, y.name
  from x
  left join y
  on x.Position between y.Start and y.End
  and x.Chr = y.chrom")

    Name  name
1 200003 geneA
2 200003 geneB
3 200260 geneB
4 400826 geneC
5 400863 geneE
6 500710 geneE