Разбить регион на более мелкие регионы на основе отсечки
Я полагаю, это довольно простая проблема программирования, но я боролся с ней. В основном потому, что я не знаю правильных слов, чтобы использовать, возможно?
Учитывая набор "диапазонов" (в виде 1-набора чисел, как показано ниже, 2-IRanges или 3-GenomicRanges), я бы хотел разделить его на набор меньших диапазонов.
Начало примера:
Chr Start End
1 1 10000
2 1 5000
Пример размера перерывов: 2000
Новый набор данных:
Chr Start End
1 1 2000
1 2001 4000
1 4001 6000
1 6001 8000
1 8001 10000
2 1 2000
2 2001 4000
2 4001 5000
Я делаю это в R. Я знаю, я мог бы генерировать это просто с seq
, но я хотел бы иметь возможность делать это на основе списка /df регионов вместо необходимости вручную делать это каждый раз, когда у меня есть новый список регионов.
Вот пример, который я сделал, используя seq:
Учитывая 22 хромосомы, проходите через них и разбивайте каждую на части
# initialize df
Regions <- data.frame(Chromosome = c(), Start = c(), End = c())
# for each row, do the following
for(i in 1:nrow(Chromosomes)){
# create a sequence from the minimum start to the max end by some value
breks <- seq(min(Chromosomes$Start[Chromosomes$Chromosome == i]), max(Chromosomes$End[Chromosomes$Chromosome == i]), by=2000000)
# put this into a dataframe
database <- data.frame(Chromosome = i, Start = breks, End = c(breks[2:length(breks)]-1, max(Chromosomes$End[Chromosomes$Chromosome == i])))
# bind with what we already have
Regions <- rbind(Regions, database)
rm(database)
}
Это прекрасно работает, мне интересно, есть ли что-то встроенное в пакет, чтобы сделать это как однострочное ИЛИ более гибкое, так как оно имеет свои ограничения.
1 ответ
Используя R / https://bioconductor.org/ пакет GenomicRanges, вот ваши начальные диапазоны
library(GenomicRanges)
rngs = GRanges(1:2, IRanges(1, c(10000, 5000)))
а затем создайте скользящее окно по всему геному, сгенерированное сначала в виде списка (один набор плиток на хромосому), а затем в списке для формата, который у вас есть в вашем вопросе
> windows = slidingWindows(rngs, width=2000, step=2000)
> unlist(windows)
GRanges object with 8 ranges and 0 metadata columns:
seqnames ranges strand
<Rle> <IRanges> <Rle>
[1] 1 [ 1, 2000] *
[2] 1 [2001, 4000] *
[3] 1 [4001, 6000] *
[4] 1 [6001, 8000] *
[5] 1 [8001, 10000] *
[6] 2 [ 1, 2000] *
[7] 2 [2001, 4000] *
[8] 2 [4001, 5000] *
-------
seqinfo: 2 sequences from an unspecified genome; no seqlengths
Принудительно из / в data.frame с as(df, "GRanges")
или же as(unlist(tiles), "data.frame")
,
Найти помощь на ?"slidingWindows,GenomicRanges-method"
(пополнение вкладки - ваш друг, ?"slidingW<tab>
).
Смущает, что это, кажется, реализовано только в версии GenomicRanges 'devel' (v. 1.25.93?); tile
делает что-то подобное, но округляет ширину диапазонов, чтобы быть примерно равной, охватывая ширину GRanges. Вот версия для бедняка
windows <- function(gr, width, withMcols=FALSE) {
starts <- Map(seq, start(rngs), end(rngs), by=width)
ends <- Map(function(starts, len) c(tail(starts, -1) - 1L, len),
starts, end(gr))
seq <- rep(seqnames(gr), lengths(starts))
strand <- rep(strand(gr), lengths(starts))
result <- GRanges(seq, IRanges(unlist(starts), unlist(ends)), strand)
seqinfo(result) <- seqinfo(gr)
if (withMcols) {
idx <- rep(seq_len(nrow(gr)), lengths(starts))
mcols(result) = mcols(gr)[idx,,drop=FALSE]
}
result
}
вызывается как
> windows(rngs, 2000)
Если подход полезен, подумайте над тем, чтобы задать дополнительные вопросы на сайте поддержки Bioconductor.