如何按 R 中的列值范围过滤行?
How to filter rows by column value ranges in R?
我有 2 个遗传数据集。一个定义每行基因组的范围,另一个数据集是基因长度范围的行,我想确保它们与第一个数据集中的范围没有任何重叠。
例如,我的数据是这样的:
#df1:
Chromosome Min Max
1 10 500
1 450 550
2 20 100
2 900 1500
2 200 210
3 5 15
4 10 20
#df2:
Gene Gene.Start Gene.End Chromosome
Gene1 10 60 1
Gene2 950 990 1
Gene3 8 14 3
我想拉 df2
中没有 Gene.Start
和 Gene.End
范围的 out/select 行,其中范围内的任何内容都在 df1
在 Min
和 Max
列中 - 重要的是,考虑到 Chromosome
数字也必须匹配。
示例的预期输出如下:
Gene Gene.Start Gene.End Chromosome
Gene2 950 990 1
Gene2
是唯一的 gene/row,其开始和结束范围不属于 Chromosome
中匹配的任何范围(查看染色体 1 中的范围)df1
.
为了编写代码,我正在尝试使用 data.table
,但我不确定如何按照我希望的方式来考虑范围。
我一直在努力让它工作,但我不确定我在做什么:
df2[df1, match := i.Gene,
on = .(Chromosome, (df2$Gene.Start > & < df2$Gene.End) > Min, (df2$Gene.Start > & < df2$Gene.End) < Max)]
Error: unexpected '&'
如何根据另一个数据帧中的范围按范围过滤数据帧?
示例输入数据:
df1 <- structure(list(Chromosome = c(1L, 1L, 2L, 2L, 2L, 3L, 4L), Min = c(10L,
450L, 20L, 900L, 200L, 5L, 10L), Max = c(500L, 550L, 100L, 1500L,
210L, 15L, 20L)), row.names = c(NA, -7L), class = c("data.table",
"data.frame"))
df2 <- structure(list(Gene = c("Gene1", "Gene2", "Gene3"), Gene.Start = c(10L,
950L, 8L), Gene.End = c(60L, 990L, 14L), Chromosome = c(1L, 1L,
3L)), row.names = c(NA, -3L), class = c("data.table", "data.frame"
))
这是一个data.table
方法
library(data.table)
# keep Gene that are not joined in the non-equi join on df1 below
df2[!Gene %in% df2[df1, on = .(Chromosome, Gene.Start >= Min, Gene.End <= Max)]$Gene, ]
# Gene Gene.Start Gene.End Chromosome
# 1: Gene2 950 990 1
这是我对 dplyr
方法的尝试。请告诉我。
library(dplyr)
library(tidyr)
df2 %>%
right_join(df1, by = "Chromosome") %>%
filter(Gene.Start<Min | Gene.Start>Max, Gene.End>Max | Gene.End>Min) %>%
distinct(Gene, Gene.Start, Gene.End, Chromosome, .keep_all = TRUE) %>%
select(Gene, Gene.Start, Gene.End, Chromosome)
输出:
Gene Gene.Start Gene.End Chromosome
1 Gene2 950 990 1
data.table
解决方案效果最好,因为它在我更大的实际数据上是最快的,但我最终还是找到了 GenomicRanges
的另一个解决方案,所以我想我也会分享给其他人的未来参考:
library(GenomicRanges)
gr1 <- makeGRangesFromDataFrame(
data.frame(
chr=df1$Chromosome,
start=df1$Min,
end=df1$Max),
keep.extra.columns=TRUE)
gr2 <- makeGRangesFromDataFrame(
data.frame(
chr=df2$Chromosome,
start=df2$Gene.Start,
end=df2$Gene.End,
Gene = df2$Gene),
keep.extra.columns=TRUE)
no_overlaps <- gr2[-queryHits(findOverlaps(gr2, gr1, type="any")),]
no_overlap_genes <- unique(no_overlaps$Gene)
gene_matches <- df2[Gene %in% no_overlap_genes]
我有 2 个遗传数据集。一个定义每行基因组的范围,另一个数据集是基因长度范围的行,我想确保它们与第一个数据集中的范围没有任何重叠。
例如,我的数据是这样的:
#df1:
Chromosome Min Max
1 10 500
1 450 550
2 20 100
2 900 1500
2 200 210
3 5 15
4 10 20
#df2:
Gene Gene.Start Gene.End Chromosome
Gene1 10 60 1
Gene2 950 990 1
Gene3 8 14 3
我想拉 df2
中没有 Gene.Start
和 Gene.End
范围的 out/select 行,其中范围内的任何内容都在 df1
在 Min
和 Max
列中 - 重要的是,考虑到 Chromosome
数字也必须匹配。
示例的预期输出如下:
Gene Gene.Start Gene.End Chromosome
Gene2 950 990 1
Gene2
是唯一的 gene/row,其开始和结束范围不属于 Chromosome
中匹配的任何范围(查看染色体 1 中的范围)df1
.
为了编写代码,我正在尝试使用 data.table
,但我不确定如何按照我希望的方式来考虑范围。
我一直在努力让它工作,但我不确定我在做什么:
df2[df1, match := i.Gene,
on = .(Chromosome, (df2$Gene.Start > & < df2$Gene.End) > Min, (df2$Gene.Start > & < df2$Gene.End) < Max)]
Error: unexpected '&'
如何根据另一个数据帧中的范围按范围过滤数据帧?
示例输入数据:
df1 <- structure(list(Chromosome = c(1L, 1L, 2L, 2L, 2L, 3L, 4L), Min = c(10L,
450L, 20L, 900L, 200L, 5L, 10L), Max = c(500L, 550L, 100L, 1500L,
210L, 15L, 20L)), row.names = c(NA, -7L), class = c("data.table",
"data.frame"))
df2 <- structure(list(Gene = c("Gene1", "Gene2", "Gene3"), Gene.Start = c(10L,
950L, 8L), Gene.End = c(60L, 990L, 14L), Chromosome = c(1L, 1L,
3L)), row.names = c(NA, -3L), class = c("data.table", "data.frame"
))
这是一个data.table
方法
library(data.table)
# keep Gene that are not joined in the non-equi join on df1 below
df2[!Gene %in% df2[df1, on = .(Chromosome, Gene.Start >= Min, Gene.End <= Max)]$Gene, ]
# Gene Gene.Start Gene.End Chromosome
# 1: Gene2 950 990 1
这是我对 dplyr
方法的尝试。请告诉我。
library(dplyr)
library(tidyr)
df2 %>%
right_join(df1, by = "Chromosome") %>%
filter(Gene.Start<Min | Gene.Start>Max, Gene.End>Max | Gene.End>Min) %>%
distinct(Gene, Gene.Start, Gene.End, Chromosome, .keep_all = TRUE) %>%
select(Gene, Gene.Start, Gene.End, Chromosome)
输出:
Gene Gene.Start Gene.End Chromosome
1 Gene2 950 990 1
data.table
解决方案效果最好,因为它在我更大的实际数据上是最快的,但我最终还是找到了 GenomicRanges
的另一个解决方案,所以我想我也会分享给其他人的未来参考:
library(GenomicRanges)
gr1 <- makeGRangesFromDataFrame(
data.frame(
chr=df1$Chromosome,
start=df1$Min,
end=df1$Max),
keep.extra.columns=TRUE)
gr2 <- makeGRangesFromDataFrame(
data.frame(
chr=df2$Chromosome,
start=df2$Gene.Start,
end=df2$Gene.End,
Gene = df2$Gene),
keep.extra.columns=TRUE)
no_overlaps <- gr2[-queryHits(findOverlaps(gr2, gr1, type="any")),]
no_overlap_genes <- unique(no_overlaps$Gene)
gene_matches <- df2[Gene %in% no_overlap_genes]