3

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?

1 Answer 1

4

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Many thanks, that's fixed it and given me further functions to learn!! Excellent, prompt response!
No problem. As it turns out, I just found a use for this very function :-). Also take a look at the rollapply family of functions in the zoo library, which are more powerful but at the price of a fixed window size (there may be a way to change it; I'm not super familiar with them).
P.S. Welcome to Stack Overflow! We hope you'll stick around the [r] tag.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.