在两个单独的列中折叠具有连续范围的行

Collapsing rows with consecutive ranges in two separate columns

非常感谢你在这方面的帮助。我正在尝试压缩一个包含 200,000 多行的数据框,其中“开始”列中一行的整数与“结束”列中的下一个连续行完全相同。作为参考,这些是染色体碱基对位置,下面是一个示例代码:

genomic_ranges <- data.frame(sample_ID = c("A", "B", "B", "B", "C"),
                         start = c(1, 20, 30, 40, 250),
                         end =  c(5, 30, 40, 70, 400),
                         feature = c("normal", "DUP", "DUP", "DUP", "DUP"))
sample_ID start end feature
1         A     1   5  "normal"
2         B    20  30     "DUP"
3         B    30  40     "DUP"
4         B    40  70     "DUP"
5         C   250 400     "DUP"

我已经尝试过逻辑向量、布尔运算符、ifelse 语句、forloops 等,我找不到方法来 1) 删除显示中间范围的行,以及 2) 将包含范围的真正开始和结束位置。

我尝试过的一些方法:

ifelse(cnv_catalogue_final$end == cnv_catalogue_final$start, "to_delete", "other"))
cnv_catalogue_final$end %in% cnv_catalogue_final$start
dplyr::filter(slice_min(start, x) | slice_max(end, x))

即使我使用这样的东西(StartA <= EndB) and (EndA >= StartB)我仍然会失去开始或结束位置。

*编辑:感谢大家的反馈!我已经用代码更新了问题。这些行确实具有由 sample_ID 标识的 ID。理想情况下,我希望 1 行具有 20-70 的完整范围,而不是将其分成 20-30、30-40 和 40-70 的段,分成 3 行,具有相同的 sample_ID 标识符。

有几种方法可以实现这一点,这里是一种:

library(tidyverse)
genomic_ranges %>%
  group_by(sample_ID) %>%
  summarize(start = min(start),
            end = max(end),
            feature = feature[1])

给出:

# A tibble: 3 x 4
  sample_ID start   end feature
  <chr>     <dbl> <dbl> <chr>  
1 A             1     5 normal 
2 B            20    70 DUP    
3 C           250   400 DUP

经过大量搜索,trial/error,并与同事聊天,我找到了另一种折叠范围的方法,通常这是我预期的非常简单的解决方案。我只是使用了 valr 包的 bed_merge() 函数。

这是特定于基因组范围的(bed_merge() 需要染色体数目 - 内置特异性耶!),并且当样本之间唯一的唯一标识符是范围时特别有用。按 sample_ID 分组仍然是必要的,因为样本之间的范围可以重叠。唯一的缺点是此功能不会在您的 df 中保留任何其他数据,因此一个键对于合并您的元数据和范围很有用。

这是一个例子:

library(tidyverse)
library(valr)
df <- data.frame(sample_ID = c("A", "B", "B", "B", "B", "B", "B", "B", "C", "C"),
                 chrom = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
                 start = c(1, 20, 30, 40, 70, 90, 100, 110, 130, 250),
                 end =  c(5, 30, 40, 70, 80, 100, 110, 130, 150, 400),
                 feature = c("normal", "DUP", "DUP", "DUP", "DUP", "DUP", "DUP", "DUP", "DUP", "DUP"))

> df    
   sample_ID chrom start end feature
1          A     1     1   5  normal
2          B     1    20  30     DUP
3          B     1    30  40     DUP
4          B     1    40  70     DUP
5          B     1    70  80     DUP
6          B     1    90 100     DUP
7          B     1   100 110     DUP
8          B     1   110 130     DUP
9          C     1   130 150     DUP
10         C     1   250 400     DUP



collapsed_df <- df %>%
  group_by(sample_ID) %>%
  bed_merge()

> collapsed_df
# A tibble: 5 × 4
# Groups:   sample_ID [3]
  sample_ID chrom start   end
  <chr>     <dbl> <int> <int>
1 A             1     1     5
2 B             1    20    80
3 B             1    90   130
4 C             1   130   150
5 C             1   250   400