Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding ranges in runs of numbers

Tags:

r

I'm trying to find runs of years in a data frame (ideally using plyr)

I'd like to get from this:

require(plyr)

dat<-data.frame(
  name=c(rep("A", 11), rep("B", 11)),
  year=c(2000:2010, 2000:2005, 2007:2011)
  )

To this:

out<-data.frame(
  name=c("A", "B", "B"),
  range=c("2000-2010", "2000-2005", "2007-2011"))

It's easy enough to identify whether each group has a continuous run of years:

ddply(dat, .(name), summarise,
      continuous=(max(year)-min(year))+1==length(year))

How do I go about breaking down group "B" into two ranges?

Any ideas or strategies would be really appreciated.

Thanks

like image 905
Ed G Avatar asked Aug 16 '13 15:08

Ed G


People also ask

How do you calculate get the range in a set of numbers?

The range is calculated by subtracting the lowest value from the highest value.

How do you find the range of scores?

The range is the simple measurement of the difference between values in a dataset. To find the range, simply subtract the lowest value from the greatest value, ignoring the others.


1 Answers

Whether you use a function from "plyr" or from base R, you need to first establish some groups. One way to detect the change in groups since your years are sequential is to look for where diff is not equal to 1. diff creates a vector of length one less than the input vector, so we'll initialize that with "1" and take the cumsum of the result.

Putting that mouthful of an explanation into practice, you can try something like this:

dat$id2 <- cumsum(c(1, diff(dat$year) != 1))

From here, you can use aggregate or your favorite grouping function to get the output you're looking for.

aggregate(year ~ name + id2, dat, function(x) paste(min(x), max(x), sep = "-"))
#   name id2      year
# 1    A   1 2000-2010
# 2    B   2 2000-2005
# 3    B   3 2007-2011

To use range with aggregate, you need to change sep to collapse, as below:

aggregate(year ~ name + id2, dat, function(x) paste(range(x), collapse = "-"))
like image 145
A5C1D2H2I1M1N2O1R2T1 Avatar answered Oct 24 '22 03:10

A5C1D2H2I1M1N2O1R2T1