Załóżmy, że start = 3, koniec = 7, i którą każdy oznaczony jako „1” na osi liczbowej począwszy od 1
starts: 0 0 1 0 0 0 0 0 0 ...
ends + 1: 0 0 0 0 0 0 0 1 0 ...
skumulowana suma rozpoczęciem minus skumulowanej sumy końcach, a różnica między nimi jest
cumsum(starts): 0 0 1 1 1 1 1 1 1 ...
cumsum(ends + 1): 0 0 0 0 0 0 0 1 1 ...
diff: 0 0 1 1 1 1 1 0 0
i lokalizacje 1 w diff są
which(diff > 0): 3 4 5 6 7
Zastosowanie tabularyzować aby umożliwić wielu startów/kończy się w tym samym miejscu, a
range2 <- function(ranges)
{
max <- max(ranges)
starts <- tabulate(ranges[,1], max)
ends <- tabulate(ranges[,2] + 1L, max)
which(cumsum(starts) - cumsum(ends) > 0L)
}
Na pytanie, co daje
> eg <- matrix(c(1, 3, 10, 5, 6, 13), 3)
> range2(eg)
[1] 1 2 3 4 5 6 10 11 12 13
Jest to dość szybko, na przykład Andrie za
> system.time(runs <- range2(xx))
user system elapsed
0.108 0.000 0.111
(Brzmi to trochę jak seque DNA nce analysis, dla której GenomicRanges może być twoim przyjacielem; używałbyś funkcji coverage
i slice
w odczytach, być może wprowadzając przy pomocy readGappedAlignments
).
Myślę, że PO chce, aby wynik zawierał jedną liczbę całkowitą tylko raz. – seancarmody
Porównałem czas: moja odpowiedź jest zdecydowanie wolniejsza! – seancarmody
@seancarmody Dziękujemy za wyróżnienie wymogu ** unikalnych ** liczb całkowitych. Będę edytować moją odpowiedź. – Andrie