在两个单独的列中折叠具有连续范围的行
Posted
技术标签:
【中文标题】在两个单独的列中折叠具有连续范围的行【英文标题】:Collapsing rows with consecutive ranges in two separate columns 【发布时间】:2021-12-09 11:41:55 【问题描述】:非常感谢您对此提供的帮助。我正在尝试压缩 200,000+ 行的数据框,其中“start”列中一行的整数与“end”列中的下一个连续行完全相同。作为参考,这些是染色体碱基对位置,以及下面的示例代码:
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 语句、forloop 等,但我找不到一种方法来 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 标识符。
【问题讨论】:
您可能想要标记您正在使用的语言。 请与dput()
分享数据,避免为表分享图片。
请提供足够的代码,以便其他人更好地理解或重现问题。
中间范围是什么意思?这些行有 ID 吗?
【参考方案1】:
有几种方法可以实现,这里是一种:
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
【讨论】:
这很简单!感谢您的回答@deschen!【参考方案2】:经过大量搜索、反复试验以及与同事聊天后,我找到了另一种折叠范围的方法,而且通常这是我所期望的非常简单的解决方案。我只是使用了 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
【讨论】:
以上是关于在两个单独的列中折叠具有连续范围的行的主要内容,如果未能解决你的问题,请参考以下文章
如果所有行的列中只有一个值,则折叠 Pandas 数据框中的行
Pandas Dataframe 保留日期在两个日期之间的行(单独的列)
比较另一个 id 下属于不同 ids 组的行并将结果打印在单独的列中