Identifying maximum number and longest set of time intervals

Viewed 226

Say I have data that look like this:

   level   start     end
1      1 133.631 825.141
2      2 133.631 155.953
3      3 146.844 155.953
4      2 293.754 302.196
5      3 293.754 302.196
6      4 293.754 301.428
7      2 326.253 343.436
8      3 326.253 343.436
9      4 333.827 343.436
10     2 578.066 611.766
11     3 578.066 611.766
12     4 578.066 587.876
13     4 598.052 611.766
14     2 811.228 825.141
15     3 811.228 825.141

or this:

   level      start        end
1      1    3.60353 1112.62000
2      2    3.60353   20.35330
3      3    3.60353    8.77526
4      2   72.03720  143.60700
5      3   73.50530  101.13200
6      4   73.50530   81.64660
7      4   92.19030  101.13200
8      3  121.28500  143.60700
9      4  121.28500  128.25900
10     2  167.19700  185.04800
11     3  167.19700  183.44600
12     4  167.19700  182.84600
13     2  398.12300  418.64300
14     3  398.12300  418.64300
15     2  445.83600  454.54500
16     2  776.59400  798.34800
17     3  776.59400  796.64700
18     4  776.59400  795.91300
19     2  906.68800  915.89700
20     3  906.68800  915.89700
21     2 1099.44000 1112.62000
22     3 1099.44000 1112.62000
23     4 1100.14000 1112.62000

They produce the following graphs:

enter image description here

As you can see there are several time intervals at different levels. The level-1 interval always spans the entire duration of the time of interest. Levels 2+ have time intervals that are shorter.

What I would like to do is select the maximum number of non-overlapping time intervals covering each period that contain the maximum number of total time within them. I have marked in pink which ones those would be.

For small dataframes it is possible to brute force this, but obviously there should be some more logical way of doing this. I'm interested in hearing some ideas about what I should try.

EDIT:

I think one thing that could help here is the column 'level'. The results come from Kleinberg's burst detection algorithm (package 'bursts'). You will note that the levels are hierarchically organized. Levels of the same number cannot overlap. However levels successively increasing e.g. 2,3,4 in successive rows can overlap.

In essence, I think the problem could be shortened to this. Take the levels produced, but remove level 1. This would be the vector for the 2nd example:

 2 3 2 3 4 4 3 4 2 3 4 2 3 2 2 3 4 2 3 2 3 4

Then, look at the 2s... if there are fewer than or only one '3' then that 2 is the longest interval. But if there are two or more 3's between successive 2's, then those 3s should be counted. Do this iteratively for each level. I think that should work...?

e.g.

vec<-df$level %>% as.vector() %>% .[-1]
vec
#[1] 2 3 2 3 4 4 3 4 2 3 4 2 3 2 2 3 4 2 3 2 3 4

max(vec) #4
vec3<-vec #need to find two or more 4's between 3s
vec3[vec3==3]<-NA  
names(vec3)<-cumsum(is.na(vec3))

 0  1  1  2  2  2  3  3  3  4  4  4  5  5  5  6  6  6  7  7  8  8 
 2 NA  2 NA  4  4 NA  4  2 NA  4  2 NA  2  2 NA  4  2 NA  2 NA  4 

vec3.res<-which(table(vec3,names(vec3))["4",]>1)
which(names(vec3)==names(vec3.res) & vec3==4) #5 6

The above identifies rows 5 and 6 (which equate to rows 6 and 7 in original df) as having two fours that lie between 3's. Perhaps something using this sort of approach might work?

1 Answers
Related