2014-11-20 64 views
2

我有一个看起来像这样两个数据帧:如何比较数据帧1的每一行与数据帧2的每一行?

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中每个名称的列表和y的名字具有相同CHROM作为Chr和(开始,结束)间隔包括位置。例如,

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运行。有一个更好的方法吗?

+0

这不是一个“应用”问题。你可以创建一个有用的,如果重要的中间与​​'merge'。 – 2014-11-20 19:41:23

+0

也许用'split'或'data.table'?我会看看我是否可以拼凑一个data.table方法。我不是最熟悉DT的人。新版本具有范围功能。我已经添加了一个标签,以查看这个珊瑚礁中是否有任何data.table-barracudas。 – 2014-11-21 02:48:38

+0

https://github.com/Rdatatable/data.table/wiki/Installation – 2014-11-21 02:53:50

回答

4

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

这里使用的是data.tablefoverlaps。首先,我们将在data.frames转换为data.tables:

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

而且,由于foverlaps作品与区间范围内,我们会为x添加一个虚拟列如下:

x[, Position2 := Position] 

现在,对于每个x,我们想知道是否Chr, Position, Position2整个落在之内任何ychrome,Start,End。 - “CHROM”与“CHR”

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 

列在您的data.frames被命名异常和套管:我们会按如下方式使用y为“关键”。使用一致的名称可能会更容易。

+0

这非常快!尽管它比我使用慢方法产生更多结果(任何想法?)。猜猜我将不得不探索'data.table'更强大的功能...... – Menglan 2014-11-21 18:35:06

+0

@Menglan,非常高兴!如果你能把我和一些测试数据联系起来(结果不同),我很乐意看看它。 – Arun 2014-11-21 19:13:18

+0

我自己做了一些测试,发现这是因为'Chr,Position,Position2'在chrome,Start,End之外''foverlaps'有NA,而这样的结果不会显示我是否使用了我的代码。谢谢! – Menglan 2014-12-05 16:26:54

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 
+0

我无法加载软件包,但输出可以接受。感谢你的回答! – Menglan 2014-11-21 02:25:16

+1

请参阅:https://code.google.com/p/sqldf/#Troubleshooting – 2014-11-21 15:03:59

相关问题