[R] Union/Intersect two continuous sets
William Dunlap
wdunlap at tibco.com
Mon Jan 16 00:29:35 CET 2012
Late last month Hans Borchers suggested the following
solution (which I trivially converted to a function):
u0 <- function(M)
{
# Mnew the union of intervals in M, an (nx2)-matrix with n > 1:
o <- order(M[, 1], M[, 2])
L <- M[o, 1]; R <- M[o, 2]
k <- 1
Mnew <- matrix(c(L[k], R[k]), 1, 2)
for (i in 2:nrow(M)) {
if (L[i] <= Mnew[k, 2]) {
Mnew[k, 2] <- max(R[i], Mnew[k, 2])
} else {
k <- k+1
Mnew <- rbind(Mnew, c(L[i], R[i]))
}
}
Mnew
}
I believe the following does the same thing. It
is quicker. It may easily be changed to give you
the intervals where p or more of the input intervals
overlap instead of the current 1 or more.
u1 <- function(M)
{
o <- order(c(M[, 1], M[, 2]))
n <- cumsum( rep(c(1, -1), each=nrow(M))[o])
startPos <- c(TRUE, n[-1]==1 & n[-length(n)]==0)
endPos <- c(FALSE, n[-1]==0 & n[-length(n)]==1)
M <- M[o]
cbind(M[startPos], M[endPos])
}
Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com
> -----Original Message-----
> From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf Of Hans W Borchers
> Sent: Thursday, December 22, 2011 7:50 AM
> To: r-help at stat.math.ethz.ch
> Subject: Re: [R] Union/Intersect two continuous sets
>
> 谢一鸣 <cutexym <at> gmail.com> writes:
>
> > Dear All,
> >
> > It is my first time using this mail list to post a question. And I
> > sincerely hope that this will not bother any subscribers.
> > So far as I know, there are functions like union( ), which can help to
> > combine two sets of discrete data. But what if the data sets are with
> > continuous data. For instance, I got three sets like [2, 4], [5, 6], [3.4,
> > 5.5]. I wonder if there is a quick solution to recognize their union is [2,
> > 6], and return the size of this union 6-2=4 to me. The similar demand is
> > for the intersection operation.
> > If you get any idea, please inform me. Thanks in advance!
> >
> > Xie
>
> I got interested in your request as I could use it myself (not for intervals,
> but a similar kind of problem).
> I assume, you represent your set of intervals as a matrix M with two columns,
> first column the left endpoints, second the right ones.
>
> Intersection is easy, as it is the interval from the maximum of left end
> points to the minimum of the right end points (or NULL if the maximum is
> greater than the minimum).
>
> For the union I didn't see a simple, i.e. one or two lines, solution ahead,
> so here is my dumb, looped version. Surely there are more elegant solutions
> coming.
>
> # Mnew the union of intervals in M, an (nx2)-matrix with n > 1:
> o <- order(M[, 1], M[, 2])
> L <- M[o, 1]; R <- M[o, 2]
> k <- 1
> Mnew <- matrix(c(L[k], R[k]), 1, 2)
> for (i in 2:nrow(M)) {
> if (L[i] <= Mnew[k, 2]) {
> Mnew[k, 2] <- max(R[i], Mnew[k, 2])
> } else {
> k <- k+1
> Mnew <- rbind(Mnew, c(L[i], R[i]))
> }
> }
>
> # Inew the intersection of intervals in M, an (nx2)-matrix with n > 1:
> L <- max(M[, 1]); R <- min(M[, 2])
> Inew <- if (L <= R) c(L, R) else c()
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
More information about the R-help
mailing list