如何对范围内的行进行分组并考虑第三列?

DN1*_*DN1 5 r dplyr data.table

我有一个遗传数据集,我想对基因组中物理上靠近的遗传变异/行进行分组。我想对每条染色体 ( chrom)基因组中某些点范围内的基因进行分组。

我的 'spots' 数据集是变体/行需要在一个范围内的位置,看起来像:

 chrom      low       high
   1        500       1700
   1        19500     20600
   5        400       1500
Run Code Online (Sandbox Code Playgroud)

Mylowhighcolumns 是我想查看下一个数据集中是否有任何行落入的范围,同时考虑到染色体 ( chrom) 也必须匹配。具有唯一范围和色度组合的每一行都是它自己的组,我希望查看我的其他数据集中是否有任何内容。

我的另一个数据集有一个位置值,我想看看它是否符合上述任何范围的匹配chrom,以便将其标记为对应于该范围,然后我可以将同一范围内的位置和 chrom 组合在一起:

Gene   chrom position 
Gene1   1    1200          
Gene2   1    10000        
Gene3   5    500 
Gene4   5    560
Gene5   1    20100           
Run Code Online (Sandbox Code Playgroud)

我已经尝试使用group_by()between()设置范围,因为看到其他与日期/时间范围相似的问题,但我正在努力解释chrom在搜索范围之前匹配数据集之间的染色体 ( )的需要。

输出看起来像:

Gene   chrom position   Group 
Gene1   1    1200          1  #position is in one of the ranges and matches the chrom so is in a group    
Gene2   1    10000        NA  #does not fit into any range on chrom 2 (no matches)
Gene3   5    500           2  #position is in one of the ranges and matches the chrom so is in a group
Gene4   5    560           2  #position is in the same range and chrom as above so joins that group
Gene5   1    20100         3  #position matches a chrom and range and so gets a group corresponding to that particular chrom and range
Run Code Online (Sandbox Code Playgroud)
  • Gene3 和 Gene4 不在第 1 组中,因为它们位于不同的组中chrom,但它们确实与 chrom 匹配并且在我的第一个数据集的第 3 行的范围内 - 因此它们会在对应于该范围和 chrom 的组中.
  • Gene5不在同一组基因1的,而它们匹配chrom它们在不同的范围lowhigh,因此获得自己的团体为独特的范围。

所以我创建一个Group在两者之间的相同范围的所有行共享数列low,并high在相同的chrom,或不适用,如果他们的立场没有任何范围匹配和CHROM在第一个数据集。

输入数据:

df1 <- 
structure(list(chrom = c(1L, 1L, 5L), 
   low = c(500L, 19500L, 400L), high = c(1700L, 20600L, 1500L
    )), row.names = c(NA, -3L), class = c("data.table", "data.frame"))

df2 <- 
structure(list(Gene = c("Gene1", "Gene2", "Gene3", "Gene4", "Gene5"
), chrom = c(1L, 1L, 5L, 5L, 1L), position = c(1200L, 10000L, 
500L, 560L, 20100L)), row.names = c(NA, -5L), class = c("data.table", 
"data.frame"))
Run Code Online (Sandbox Code Playgroud)

我还在考虑为每个唯一范围和色度组合提供我的第一个数据集唯一标识符,然后将该标识符分配给数据集 2 中也匹配该组合的任何行,以便该标识符创建我的组号列。虽然我的真实数据是 2.3k 行范围和 82k 行匹配到共享组,所以我在运行 dplyr 选项时也遇到了问题,我通常会尝试。

den*_*nis 3

您可以在以下位置使用非等值连接data.table

library(data.table)
df1 <- setDT(df1)
df2 <- setDT(df2)

df1[,group := 1:.N]
df1[df2,on = .(chrom, low < position, high > position)]


   chrom   low  high group  Gene
1:     1  1200  1200     1 Gene1
2:     1 10000 10000    NA Gene2
3:     5   500   500     3 Gene3
4:     5   560   560     3 Gene4
5:     1 20100 20100     2 Gene5
Run Code Online (Sandbox Code Playgroud)

这里我首先为每一行设置了一个组df1。合并后,如果满足条件,则该行将关联到一个组。

非等合并不是超级直观的,但超级强大且明确:合并条件.(chrom, low < position, high > position)从字面上看就是您明确表示的(您想要相同的染色体,并且位置在低和高之间)。

data.table,当你这样做时

df1[df2,on = something]
Run Code Online (Sandbox Code Playgroud)

df1用满足df2表示的条件的行进行子集化on。如果是和something的公共变量,那么它等价于df1df2

merge(df1,df2,all.y = T,by = "someting")
Run Code Online (Sandbox Code Playgroud)

something可以是两个数据表的变量之间的变量和条件列表。这里,.()表示一个列表,.(chrom,low < position, high > position)表示您合并变量chrom(两个 data.table 之间相同), 和low < position, 和high > position。当表达不等式时,必须从主 data.table 中的变量(df1此处)开始,然后是子集 data.table 中的变量(df2)。

使用不等式的非等值合并的输出将主 data.table 的不等式中表示的变量(即df1)替换为子集 data.table 的变量(即df2此处),依此类推lowhigh成为position。如果您想保留lowhigh值,您应该将它们复制到其他变量中,或者合并这些变量的副本。

您实际上可以进行相反的合并,我们可以在相同的条件下df2按条目进行子集化:df1

df2[df1,on = .(chrom,position >low , position<high)]

    Gene chrom position position.1 group
1: Gene1     1      500       1700     1
2: Gene5     1    19500      20600     2
3: Gene3     5      400       1500     3
4: Gene4     5      400       1500     3
Run Code Online (Sandbox Code Playgroud)

在这里,您对满足 中表示的条件df1的条目进行子集化,并获得实际属于某个组的列表(不在这里,因为它与子集不匹配)。df2on = .()GeneGene2

与上面的解释类似,这里position变成lowhigh


编辑

我刚刚看到@DavidArenburg 的评论,它是我提出和解释的内容的更简洁、更好的版本:

df2[, grp := df1[.SD, which = TRUE, on = .(chrom, low <= position, high >= position)]]
Run Code Online (Sandbox Code Playgroud)

使用直接将非等值合并的结果关联df1[df2,on = .(chrom, low < position, high > position)]到组变量,这会给出满足 合并条件的which = TRUE行。df2df1[df2 , on =....]