首页 > 解决方案 > 如何根据另一个数据集设置的条件对行进行分组?

问题描述

我试图根据类似的问题编写一个答案,但是我正在努力让任何答案完全适合我的用例。

我有 2 个遗传数据集(查看基因组中突变的位置)。

这些看起来像:

#df1:
Chromosome  Min     Max   Group
1           500     1000    1
1           400     1900    2
2           300     400     3
3           2000    2100    4
#df2
Gene    Chromosome  Position
Gene1          1    600
Gene1          1    650 
Gene2          1    1700
Gene3          2    350
Gene4          2    355
Gene5          2    450
Gene6          3    2050

我正在寻找哪些行df2属于哪个Groupdf1 - 所以我正在编码询问行中的行df2是否具有匹配的Chromosome数字并且Position列值是否在Max和的Min列之间的范围内df1,然后如果它分配该行相同Group中的数字df1df2如果它们出现在多个组中,我希望这也能复制行。

该示例的预期输出为:

Gene    Chromosome  Position   Group
Gene1          1    600          1
Gene1          1    650          1 
Gene1          1    600          2
Gene1          1    650          2 
Gene2          1    1700         2
Gene3          2    350          3
Gene4          2    355          3 
Gene5          2    450          NA
Gene6          3    2050         4

#Gene1 enters both groups 1 and 2 as their Chromosome and Position fits in both those groups of df1

我想要得到的关键是我缺少的一些组在df1它们的最小-最大范围内重叠,但我仍然希望保留每个单独的组,并且只df2复制基因/行,因为它们的位置可能匹配多个重叠的组。

目前我正在尝试使用以下代码进行编码:

df1$ID <- seq.int(nrow(df1))
df2$ID<- seq.int(nrow(df2))

df2[df1, Group := i.ID, on = .(Chromosome, Position > Min, Position < Max ) ]

对于我的示例,此输出:

Gene  Chromosome Position  ID Group
Gene1   1           600     1   2
Gene1   1           650     2   2
Gene2   1           1700    3   2
Gene3   2           350     4   3
Gene4   2           355     5   3
Gene5   2           450     6   NA
Gene6   3           2050    7   4

所以在这种情况下,因为第 1 组和第 2 组在它们的最小-最大范围内有重叠,所以第 1 组已经从输出结果中丢失了。有没有另一种方法可以编码来避免这种情况并匹配行,但Groups尽管有任何范围重叠,但仍保持所有内容?

我尝试了其他方法来使用类似的问题(How to perform join over date range using data.table?)使用foverlaps(),但这也不能按预期工作。

输入数据:

df1 <-
structure(list(Chromosome = c(1L, 1L, 2L, 3L), Min = c(500L, 
400L, 300L, 2000L), Max = c(1000L, 1900L, 400L, 2100L), Group = 1:4, 
    ID = 1:4), row.names = c(NA, -4L), class = c("data.table", 
"data.frame"))

df2 <-
structure(list(Gene = c("Gene1", "Gene1", "Gene2", "Gene3", "Gene4", 
"Gene5", "Gene6"), Chromosome = c(1L, 1L, 1L, 2L, 2L, 2L, 3L), 
    Position = c(600L, 650L, 1700L, 350L, 355L, 450L, 2050L)), row.names = c(NA, 
-7L), class = c("data.table", "data.frame"))

标签: rdata.tablebioinformatics

解决方案


你在寻找这样的东西吗?

setDT(df1)
setDT(df2)

df2[, Group := df1[.SD, 
                   on = .(Chromosome = Chromosome, Max > Position, Min < Position), 
                   toString(Group), 
                   by = .EACHI]$V1]

#     Gene Chromosome Position Group
# 1: Gene1          1      600  1, 2
# 2: Gene1          1      650  1, 2
# 3: Gene2          1     1700     2
# 4: Gene3          2      350     3
# 5: Gene4          2      355     3
# 6: Gene5          2      450    NA
# 7: Gene6          3     2050     4

推荐阅读