如何匹配另一个数据集范围内的行
How to match rows within in a range of another dataset
我有一个遗传数据集,我在其中匹配 1 个文件的基因组中的染色体位置,前提是它们符合另一个文件中给定的染色体位置范围。
我试过类似的问题,主要是时间间隔,但由于我需要确保染色体数也匹配(所以我不匹配相同的位置但它们没有用)在不同的染色体上)
我的数据是这样的:
#df1 - chromosome positions to find within df2 ranges:
Chromosome Position Start End
1 101 101 101
2 101 101 101
3 600 600 600
#df2 - genomic ranges
Chromosome Start End CpG
1 50 200 10
1 300 400 2
4 100 200 5
预期的匹配输出(最终我也在寻找 df1 数据的匹配 CpG
列):
Chromosome Position Start End CpG
1 101 50 200 10 #only row of df1 that's within a range on df2 on the same chromosome
我目前正在尝试使用:
df <-df1 %>%
left_join(df2,
by = "Chromosome") %>%
filter(Position >= Start & Position <= End)
Error: Problem with `filter()` input `..1`.
x object 'Start' not found
i Input `..1` is `Position >= Start & Position <= End`.
我不明白我是怎么得到这个错误的,开始和结束列存在于两个文件中并且都是整数数据类 - 有没有我遗漏的东西或我可以解决的其他方法这个?
我的实际数据非常大,所以如果 data.table
解决方案适用于此,我也在尝试找到它 - 我试过了,但我是新手,还没有走得太远:
df1[df2, on = .(Chromosome, Position > End, Position < Start ) ]
编辑:尝试重叠:
setkey(df1)
df2[, End := Start]
foverlaps(df2, df1, by.x = names(df2), type = "within", mult = "all", nomatch = 0L)
Error in foverlaps(df2, df1, by.x = names(df2), type = "within", mult = "all", :
length(by.x) != length(by.y). Columns specified in by.x should correspond to columns specified in by.y and should be of same lengths.
问题与 left_join()
相关,它将来自不同数据集的同名列堆叠在一个数据集中。由于同一数据集中的两列不能具有相同的列名,因此 Start 和 End 列的名称更改为 Start.x,并且 Start.y、End.x、End.y.
因此,您必须从第一个数据集中删除开始和结束列,如下所示:
library(data.table)
library(tidyr)
library(dplyr)
df1 <- fread("Chromosome Position Start End
1 101 101 101
2 101 101 101
3 600 600 600")
df2<- fread("Chromosome Start End CpG
1 50 200 10
1 300 400 2
4 100 200 5")
df <-df1 %>%select(Chromosome, Position)%>%
left_join(df2,
by = "Chromosome") %>%
filter(Position >= Start & Position <= End)
或引用列的真实名称,然后删除多余的列:
df <-df1 %>%
left_join(df2,
by = "Chromosome") %>%
filter(Position >= Start.y & Position <= End.y)
干杯!
对于 data.table
解决方案,您应该查看 Arun 在@Henrik 提供的 link 中关于非等值连接的第二个答案。
Overlap join with start and end positions
基于此,我们有
library(data.table)
df1 <- data.table(Chromosome=1:3,Position=c(101,101,600),
Start=c(101,101,600),End=c(101,101,600))
df2 <- data.table(Chromosome=c(1,1,4),
Start=c(50,300,100),End=c(200,400,200),CpG=c(10,2,5))
df1[df2,.(Chromosome,Position=x.Position,Start,End,CpG),
on=.(Chromosome,Position>=Start,Position<=End),nomatch=0L]
给予
Chromosome Position Start End CpG
1: 1 101 101 101 10
这不太正确,因为它需要 Start
和 End
来自 df1
而不是 df2
。为什么 df1
中还有 Start
和 End
?
一种处理方法是不将它们包含在连接语句中:
df1[,.(Chromosome,Position)][df2,
.(Chromosome,Position=x.Position,Start,End,CpG),
on=.(Chromosome,Position>=Start,Position<=End),nomatch=0L]
给予
Chromosome Position Start End CpG
1: 1 101 50 200 10
[编辑以注意@Carles Sans Fuentes 在他的 dplyr
回答中发现了同样的问题。]
为了检查更多匹配的案例,我添加了更多数据:
df1 <- data.table(Chromosome=c(1,1:4),Position=c(350,101,101,600,200),
Start=c(350,101,101,600,200),End=c(350,101,101,600,200))
df1
Chromosome Position Start End
1: 1 350 350 350
2: 1 101 101 101
3: 2 101 101 101
4: 3 600 600 600
5: 4 200 200 200
df1[,.(Chromosome,Position)][df2,
.(Chromosome,Position=x.Position,Start,End,CpG),
on=.(Chromosome,Position>=Start,Position<=End),nomatch=0L]
Chromosome Position Start End CpG
1: 1 101 50 200 10
2: 1 350 300 400 2
3: 4 200 100 200 5
我想这就是您想要的。
我有一个遗传数据集,我在其中匹配 1 个文件的基因组中的染色体位置,前提是它们符合另一个文件中给定的染色体位置范围。
我试过类似的问题,主要是时间间隔,但由于我需要确保染色体数也匹配(所以我不匹配相同的位置但它们没有用)在不同的染色体上)
我的数据是这样的:
#df1 - chromosome positions to find within df2 ranges:
Chromosome Position Start End
1 101 101 101
2 101 101 101
3 600 600 600
#df2 - genomic ranges
Chromosome Start End CpG
1 50 200 10
1 300 400 2
4 100 200 5
预期的匹配输出(最终我也在寻找 df1 数据的匹配 CpG
列):
Chromosome Position Start End CpG
1 101 50 200 10 #only row of df1 that's within a range on df2 on the same chromosome
我目前正在尝试使用:
df <-df1 %>%
left_join(df2,
by = "Chromosome") %>%
filter(Position >= Start & Position <= End)
Error: Problem with `filter()` input `..1`.
x object 'Start' not found
i Input `..1` is `Position >= Start & Position <= End`.
我不明白我是怎么得到这个错误的,开始和结束列存在于两个文件中并且都是整数数据类 - 有没有我遗漏的东西或我可以解决的其他方法这个?
我的实际数据非常大,所以如果 data.table
解决方案适用于此,我也在尝试找到它 - 我试过了,但我是新手,还没有走得太远:
df1[df2, on = .(Chromosome, Position > End, Position < Start ) ]
编辑:尝试重叠:
setkey(df1)
df2[, End := Start]
foverlaps(df2, df1, by.x = names(df2), type = "within", mult = "all", nomatch = 0L)
Error in foverlaps(df2, df1, by.x = names(df2), type = "within", mult = "all", :
length(by.x) != length(by.y). Columns specified in by.x should correspond to columns specified in by.y and should be of same lengths.
问题与 left_join()
相关,它将来自不同数据集的同名列堆叠在一个数据集中。由于同一数据集中的两列不能具有相同的列名,因此 Start 和 End 列的名称更改为 Start.x,并且 Start.y、End.x、End.y.
因此,您必须从第一个数据集中删除开始和结束列,如下所示:
library(data.table)
library(tidyr)
library(dplyr)
df1 <- fread("Chromosome Position Start End
1 101 101 101
2 101 101 101
3 600 600 600")
df2<- fread("Chromosome Start End CpG
1 50 200 10
1 300 400 2
4 100 200 5")
df <-df1 %>%select(Chromosome, Position)%>%
left_join(df2,
by = "Chromosome") %>%
filter(Position >= Start & Position <= End)
或引用列的真实名称,然后删除多余的列:
df <-df1 %>%
left_join(df2,
by = "Chromosome") %>%
filter(Position >= Start.y & Position <= End.y)
干杯!
对于 data.table
解决方案,您应该查看 Arun 在@Henrik 提供的 link 中关于非等值连接的第二个答案。
Overlap join with start and end positions
基于此,我们有
library(data.table)
df1 <- data.table(Chromosome=1:3,Position=c(101,101,600),
Start=c(101,101,600),End=c(101,101,600))
df2 <- data.table(Chromosome=c(1,1,4),
Start=c(50,300,100),End=c(200,400,200),CpG=c(10,2,5))
df1[df2,.(Chromosome,Position=x.Position,Start,End,CpG),
on=.(Chromosome,Position>=Start,Position<=End),nomatch=0L]
给予
Chromosome Position Start End CpG
1: 1 101 101 101 10
这不太正确,因为它需要 Start
和 End
来自 df1
而不是 df2
。为什么 df1
中还有 Start
和 End
?
一种处理方法是不将它们包含在连接语句中:
df1[,.(Chromosome,Position)][df2,
.(Chromosome,Position=x.Position,Start,End,CpG),
on=.(Chromosome,Position>=Start,Position<=End),nomatch=0L]
给予
Chromosome Position Start End CpG
1: 1 101 50 200 10
[编辑以注意@Carles Sans Fuentes 在他的 dplyr
回答中发现了同样的问题。]
为了检查更多匹配的案例,我添加了更多数据:
df1 <- data.table(Chromosome=c(1,1:4),Position=c(350,101,101,600,200),
Start=c(350,101,101,600,200),End=c(350,101,101,600,200))
df1
Chromosome Position Start End
1: 1 350 350 350
2: 1 101 101 101
3: 2 101 101 101
4: 3 600 600 600
5: 4 200 200 200
df1[,.(Chromosome,Position)][df2,
.(Chromosome,Position=x.Position,Start,End,CpG),
on=.(Chromosome,Position>=Start,Position<=End),nomatch=0L]
Chromosome Position Start End CpG
1: 1 101 50 200 10
2: 1 350 300 400 2
3: 4 200 100 200 5
我想这就是您想要的。