2sb
2sb

Reputation: 649

R - Difference between two rows depending on condition

I have a time series:

dDate=seq(as.POSIXct("2012/1/1"), as.POSIXct("2012/1/10"), "day")  
dDate  
 [1] "2012-01-01 PST" "2012-01-02 PST" "2012-01-03 PST" "2012-01-04 PST" "2012-01-05 PST"       "2012-01-06 PST" "2012-01-07 PST" "2012-01-08 PST" "2012-01-09 PST"
 [10] "2012-01-10 PST"

values <- c(F,T,T,T,F,F,T,T,F,F)
> dframe <- data.frame(time=dDate,values=values)  
> dframe
  time values
  1  2012-01-01  FALSE 
  2  2012-01-02   TRUE
  3  2012-01-03   TRUE
  4  2012-01-04   TRUE 
  5  2012-01-05  FALSE  
  6  2012-01-06  FALSE  
  7  2012-01-07   TRUE  
  8  2012-01-08   TRUE   
  9  2012-01-09  FALSE 
  10 2012-01-10  FALSE

I want to know the interval during which the values were true.

Expected Result:

  StartTime          Diff(day)
  2012-01-02         3
  2012-01-07         2 

Upvotes: 0

Views: 660

Answers (2)

Matthew Plourde
Matthew Plourde

Reputation: 44614

You can do:

with(dframe, data.frame(StartTime = time[diff(c(FALSE, values)) == 1], 
                        Days = with(rle(values), lengths[values])))

The nameing is a little unfortunate. values in lengths[values] is not your values col, but the values element of the rle object.

Upvotes: 1

Chris Taylor
Chris Taylor

Reputation: 47382

How about this?

> secsPerDay <- 24 * 60 * 60
> switch     <- c(NA, diff(values))
> startTime  <- dDate[switch==1]
> endTime    <- dDate[switch==-1]
> period     <- (as.numeric(endTime) - as.numeric(startTime)) / secsPerDay
> result     <- data.frame(startTime=startTime[-1], period=period[-1])

Upvotes: 1

Related Questions