如何计算长格式数据框架的增长率?

use*_*397 12 math r dataframe

数据结构如下......

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

我很难在类别中创建增长率列(按年).任何人都可以帮助代码创建这样的东西......

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  
Run Code Online (Sandbox Code Playgroud)

Ben*_*ker 16

对于这些问题("我如何根据YYY类别计算XXX")?总有一些基于解决方案by()data.table()包装和plyr.我通常更喜欢plyr,往往更慢,但(对我来说)更透明/优雅.

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))
Run Code Online (Sandbox Code Playgroud)

这个答案和@ krlmr之间的主要区别在于我使用的是几何平均技巧(记录日志差异然后取幂),而@krlmr计算显式比率.

在数学上,diff(log(Value))是采取日志的差异,即log(x[t+1])-log(x[t])对所有t.当我们取得指数时,我们得到比率x[t+1]/x[t](因为exp(log(x[t+1])-log(x[t])) = exp(log(x[t+1]))/exp(log(x[t])) = x[t+1]/x[t]).OP需要分数变化而不是乘法增长率(即x[t+1]==x[t]对应于零的分数变化而不是乘法增长率1.0),因此我们减去1.

我也在使用transform()一些额外的"语法糖",以避免创建一个新的匿名函数.


Jil*_*ina 6

使用R基函数(ave)

> dfdf$Growth <- with(df, ave(Value, Category, 
                      FUN=function(x) c(NA, diff(x)/x[-length(x)]) ))
> df
   Category Year Value     Growth
1         A 2010     1         NA
2         A 2011     2 1.00000000
3         A 2012     3 0.50000000
4         A 2013     4 0.33333333
5         A 2014     5 0.25000000
6         A 2015     6 0.20000000
7         B 2010     7         NA
8         B 2011     8 0.14285714
9         B 2012     9 0.12500000
10        B 2013    10 0.11111111
11        B 2014    11 0.10000000
12        B 2015    12 0.09090909
Run Code Online (Sandbox Code Playgroud)

@Ben Bolker的答案很容易适应ave:

transform(df, Growth=ave(Value, Category, 
                         FUN=function(x) c(NA,exp(diff(log(x)))-1)))
Run Code Online (Sandbox Code Playgroud)


小智 6

您可以简单地使用dplyr包:

> df %>% group_by(Category) %>% mutate(Growth = (Value - lag(Value))/lag(Value))  
Run Code Online (Sandbox Code Playgroud)

这将产生以下结果:

# A tibble: 12 x 4
# Groups:   Category [2]
   Category  Year Value  Growth
   <fct>    <int> <int>   <dbl>
 1 A         2010     1 NA     
 2 A         2011     2  1     
 3 A         2012     3  0.5   
 4 A         2013     4  0.333 
 5 A         2014     5  0.25  
 6 A         2015     6  0.2   
 7 B         2010     7 NA     
 8 B         2011     8  0.143 
 9 B         2012     9  0.125 
10 B         2013    10  0.111 
11 B         2014    11  0.1   
12 B         2015    12  0.0909
Run Code Online (Sandbox Code Playgroud)