31

I have a time series object in R with multiple vectors. I would like to calculate the period-over-period percentage change at each point in time (save t = 1, which would obviously be NA) for each vector.

> data <- ts(data.frame(x1=c(1:10), x2=c(11:20), x3=c(21:30)), start = c(2010,3), frequency = 4)
> data
        x1 x2 x3
2010 Q3  1 11 21
2010 Q4  2 12 22
2011 Q1  3 13 23
2011 Q2  4 14 24
2011 Q3  5 15 25
2011 Q4  6 16 26
2012 Q1  7 17 27
2012 Q2  8 18 28
2012 Q3  9 19 29
2012 Q4 10 20 30
E. Vincenti
  • 377
  • 1
  • 6
  • 11

2 Answers2

57

Try this:

R> data/stats::lag(data,-1) - 1
         data.x1   data.x2   data.x3
2010 Q4 1.000000 0.0909091 0.0476190
2011 Q1 0.500000 0.0833333 0.0454545
2011 Q2 0.333333 0.0769231 0.0434783
2011 Q3 0.250000 0.0714286 0.0416667
2011 Q4 0.200000 0.0666667 0.0400000
2012 Q1 0.166667 0.0625000 0.0384615
2012 Q2 0.142857 0.0588235 0.0370370
2012 Q3 0.125000 0.0555556 0.0357143
2012 Q4 0.111111 0.0526316 0.0344828
R> 
coding_is_fun
  • 117
  • 1
  • 14
Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
  • I knew there was a brilliantly simple solution. Thank you! – E. Vincenti Jan 30 '13 at 22:25
  • 2
    You are welcome. You can now 'accept' (click on the tickmark) or 'upvote' the answers. You can upvote several, but accept only one. – Dirk Eddelbuettel Jan 30 '13 at 22:27
  • 2
    I get this error: Error in lag.default(data, -1) : n must be a single positive integer – Steve Rowe Jun 20 '15 at 08:52
  • This has probably changed in newer version of `dplyr`. In `dplyr 0.4.3`, it should be `lag(data, 1)`. There is another function called `lead` for comparing offset in upcoming values. So, negative value for `n` shouldn't make any sense. Using negative value for `n` gives error. – narendra-choudhary Mar 27 '16 at 13:38
  • 3
    Please do not use dplyr in this context. It hides base R functions of the same name which is incredibly bad practice. – Dirk Eddelbuettel Mar 27 '16 at 16:55
  • @DirkEddelbuettel Thx for the above info. I wonder that does dplyr still hide base R functions in its 0.5.0 version. Also, one of my functions that works well before dplyr install/load, gave error after the install/load of dplyr. – Erdogan CEVHER Oct 15 '16 at 03:29
  • I wonder if that is really correct. Shouldn't each row have their own percentage change (starting at 2010 Q4)? (it does work when there is only one time series in the `ts` object though.) – Marcelo Avila Jun 13 '18 at 17:46
20

Something like this?

> diff(data)/data[-nrow(data),] * 100
               x1       x2       x3
2010 Q4 100.00000 9.090909 4.761905
2011 Q1  50.00000 8.333333 4.545455
2011 Q2  33.33333 7.692308 4.347826
2011 Q3  25.00000 7.142857 4.166667
2011 Q4  20.00000 6.666667 4.000000
2012 Q1  16.66667 6.250000 3.846154
2012 Q2  14.28571 5.882353 3.703704
2012 Q3  12.50000 5.555556 3.571429
2012 Q4  11.11111 5.263158 3.448276
Jilber Urbina
  • 58,147
  • 10
  • 114
  • 138