Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
547 views
in Technique[技术] by (71.8m points)

r - How calculate growth rate in long format data frame?

With data structured as follows...

df <- data.frame(Category=c(rep("A",6),rep("B",6)),
      Year=rep(2010:2015,2),Value=1:12)

I'm having a tough time creating a growth rate column (by year) within category. Can anyone help with code to create something like this...

Category Year Value Growth  
    A   2010    1   
    A   2011    2   1.000  
    A   2012    3   0.500  
    A   2013    4   0.333  
    A   2014    5   0.250  
    A   2015    6   0.200  
    B   2010    7     
    B   2011    8   0.143  
    B   2012    9   0.125  
    B   2013    10  0.111  
    B   2014    11  0.100  
    B   2015    12  0.091  
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

For these sorts of questions ("how do I compute XXX by category YYY")? there are always solutions based on by(), the data.table() package, and plyr. I generally prefer plyr, which is often slower, but (to me) more transparent/elegant.

df <- data.frame(Category=c(rep("A",6),rep("B",6)),
  Year=rep(2010:2015,2),Value=1:12)


library(plyr)
ddply(df,"Category",transform,
         Growth=c(NA,exp(diff(log(Value)))-1))

The main difference between this answer and @krlmr's is that I am using a geometric-mean trick (taking differences of logs and then exponentiating) while @krlmr computes an explicit ratio.

Mathematically, diff(log(Value)) is taking the differences of the logs, i.e. log(x[t+1])-log(x[t]) for all t. When we exponentiate that we get the ratio x[t+1]/x[t] (because exp(log(x[t+1])-log(x[t])) = exp(log(x[t+1]))/exp(log(x[t])) = x[t+1]/x[t]). The OP wanted the fractional change rather than the multiplicative growth rate (i.e. x[t+1]==x[t] corresponds to a fractional change of zero rather than a multiplicative growth rate of 1.0), so we subtract 1.

I am also using transform() for a little bit of extra "syntactic sugar", to avoid creating a new anonymous function.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...