我有两个看起来像这样的数据框
a
Id start stop
1 ABC 25 30
2 ACD 40 60
3 BCD 55 60
b
Id start stop
1 XYZ 20 50
2 ZXY 80 90
3 YZX 50 70
我想合并两个数据帧中的ID并将它们放入一个新的(如下所示),如果第一个数据帧中start列中的值较高而stop列中的值较低第一个数据框。因此,当[1,2]在a中高于[1,2]并且a中的[1,3]低于[1,3]时,两个数据帧中的id [1,1]变为进入新的数据框架。
1 ABC XYZ
2 BCD YZX
我正在尝试使用for循环执行此操作,如下所示,但似乎无法让它按我的意愿工作。任何帮助表示赞赏。我对R也很新,所以请保持简单:-)
a<-dataframe1
b<-dataframe2
for (i in 1:nrow(a)) {
for (j in 1:nrow(b)) {
if (a[i,2]>b[j,2] & a[i,3]<b[j,3]) {
z<-as.data.frame(cbind(a[i,1],b[j,1]))
}
}
}
答案 0 :(得分:2)
使用data.table
的解决方案可以实现为:
library(data.table)
setDT(a)
setDT(b)
a[b, .(Id_a = Id, Id_b = i.Id), on=.(start>=start , stop<=stop), nomatch = 0]
# Id_a Id_b
# 1: ABC XYZ
# 2: BCD YZX
选项#2:使用库sqldf
library(sqldf)
sqldf("SELECT a.ID as Id_a, b.ID as Id_b
FROM a, b
WHERE a.start >= b.start AND a.stop <= b.stop")
# Id_a Id_b
# 1 ABC XYZ
# 2 BCD YZX
数据强>
a <- read.table(text =
"Id start stop
ABC 25 30
ACD 40 60
BCD 55 60",
header = TRUE, stringsAsFactors = FALSE)
b <- read.table(text =
"Id start stop
XYZ 20 50
ZXY 80 90
YZX 50 70",
header = TRUE, stringsAsFactors = FALSE)
答案 1 :(得分:1)
以下是使用R / Bioconductor库findOverlaps
中的GenomicRanges
的一种可能性:
library(GenomicRanges);
gr.a <- makeGRangesFromDataFrame(cbind.data.frame(seqnames = 1, a), keep = T);
gr.b <- makeGRangesFromDataFrame(cbind.data.frame(seqnames = 1, b), keep = T);
hits <- findOverlaps(gr.a, gr.b, type = "within");
cbind.data.frame(
from_a = mcols(gr.a[queryHits(hits)])$Id,
from_b = mcols(gr.b[subjectHits(hits)])$Id)
# from_a from_b
#1 ABC XYZ
#2 BCD YZX
注意:我在这里使用GenomicRanges
因为它的间隔操作不同;似乎R库intervals
提供了类似的功能。
a <- read.table(text =
"Id start stop
1 ABC 25 30
2 ACD 40 60
3 BCD 55 60", header = T, row.names = 1)
b <- read.table(text =
"Id start stop
1 XYZ 20 50
2 ZXY 80 90
3 YZX 50 70", header = T, row.names = 1)