Reputation: 2754
I have a vector of binary variables which state whether a product is on promotion in the period. I'm trying to work out how to calculate the duration of each promotion and the duration between promotions.
promo.flag = c(1,1,0,1,0,0,1,1,1,0,1,1,0))
So in other words: if promo.flag
is same as previous period then running.total + 1
, else running.total
is reset to 1
I've tried playing with apply functions and cumsum but can't manage to get the conditional reset of running total working :-(
The output I need is:
promo.flag = c(1,1,0,1,0,0,1,1,1,0,1,1,0)
rolling.sum = c(1,2,1,1,1,2,1,2,3,1,1,2,0)
Can anybody shed any light on how to achieve this in R?
Upvotes: 3
Views: 1643
Reputation: 72731
It sounds like you need run length encoding (via the rle
command in base R).
unlist(sapply(rle(promo.flag)$lengths,seq))
Gives you a vector 1 2 1 1 1 2 1 2 3 1 1 2 1
. Not sure what you're going for with the zero at the end, but I assume it's a terminal condition and easy to change after the fact.
This works because rle()
returns a list of two, one of which is named lengths
and contains a compact sequence of how many times each is repeated. Then seq
when fed a single integer gives you a sequence from 1 to that number. Then apply repeatedly calls seq
with the single numbers in rle()$lengths
, generating a list of the mini sequences. unlist
then turns that list into a vector.
Upvotes: 4