使用python熊猫或R:
我有一个数据框架A,具有数百万行:
CHR SNP POS
1 rs2073813 753541
1 rs3131969 754182
2 rs3131968 754192
2 rs3131967 754334
3 rs3115859 754503
3 rs3131966 900000
和另一个数据框B(也有数百万行):
CHR start end
1 700500 833300
2 1000 20000
2 59998 60000
3 700000 800000
对于A中的每个“ POS”,我要检查它是否存在于B的“开始”和“结束”给定的范围内(检查B中的每一行)。另外,A中的CHR也应与B中的CHR相匹配。如果满足这些条件,则在A中打印行。A中的行是唯一的,并根据A中的POS进行排序。B中的每一行也是唯一的。
例如,A的POS 753541处于700500到833300的范围内,A的CHR = 1和CHR = 1 B也匹配,因此打印:
1 rs2073813 753541
最后,我想获得一个像这样的数据帧C:
CHR SNP POS
1 rs2073813 753541
1 rs3131969 754182
3 rs3115859 754503
答案 0 :(得分:1)
使用data.table
设置示例数据:
library(data.table)
A <- data.table(CHR = c(1,1,2,2,3,3), SNP = c('rs2073813', 'rs3131969', 'rs3131968', 'rs3131967', 'rs3115859', 'rs3131966'), POS = c(753541,754182,754192,754334,754503,900000))
B <- data.table(CHR = c(1,2,2,3), start = c(700500, 1000, 59998, 700000), end = c(833300, 20000, 60000, 800000))
然后在A
上合并B
和CHR
:
merged_all <- merge(x = A, y = B, on = 'CHR')
然后过滤合并的数据,使其仅包含满足您条件的行和列:
out <- merged_all[(POS > start & end > POS), .(CHR, SNP, POS)]
> out
CHR SNP POS
1: 1 rs2073813 753541
2: 1 rs3131969 754182
3: 3 rs3115859 754503
编辑:
使用更有效的选项进行更新:
out <- A[B, on = .(CHR, POS >= start, POS <= end), .(CHR, SNP, POS), nomatch = 0]
> out
CHR SNP POS
1: 1 rs2073813 700500
2: 1 rs3131969 700500
3: 3 rs3115859 700000
这将直接连接表。
注意:尚不清楚您是否需要包含范围或排除范围(>
或>=
)。您可以据此进行调整。
答案 1 :(得分:1)
在his edit, cddt has suggested中使用非等额联接。
不幸的是,非等额联接有些棘手。为了产生预期的结果,我们需要告诉我们从第一个数据表中选择POS
。表A
:
library(data.table)
setDT(A) # coerce to data.table
setDT(B)
A[B, on = .(CHR, POS >= start, POS <= end), .(CHR, SNP, x.POS), nomatch = 0]
CHR SNP POS 1: 1 rs2073813 753541 2: 1 rs3131969 754182 3: 3 rs3115859 754503
这是通过前缀x.
或者,(也许有些直观),我们可以通过以下方式返回匹配行的行索引:
A[B, on = .(CHR, POS >= start, POS <= end), nomatch = 0, which = TRUE]
[1] 1 2 5
和相应的子集A
:
A[A[B, on = .(CHR, POS >= start, POS <= end), nomatch = 0, which = TRUE]]
CHR SNP POS 1: 1 rs2073813 753541 2: 1 rs3131969 754182 3: 3 rs3115859 754503
foverlaps()
这是一种不太优雅的选择:
foverlaps(A[, POS2 := POS], setkey(B), by.x = c("CHR", "POS", "POS2"), nomatch = 0)
CHR start end SNP POS POS2 1: 1 700500 833300 rs2073813 753541 753541 2: 1 700500 833300 rs3131969 754182 754182 3: 3 700000 800000 rs3115859 754503 754503
library(data.table)
A <- fread("CHR SNP POS
1 rs2073813 753541
1 rs3131969 754182
2 rs3131968 754192
2 rs3131967 754334
3 rs3115859 754503
3 rs3131966 900000")
B <- fread("CHR start end
1 700500 833300
2 1000 20000
2 59998 60000
3 700000 800000")