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

时间:2013-11-06 22:56:21

标签: r math dataframe

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

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

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

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  

7 个答案:

答案 0 :(得分:14)

对于这些问题(“我如何根据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))

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

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

我还使用x[t+1]==x[t]来获得一些额外的“语法糖”,以避免创建一个新的匿名函数。

答案 1 :(得分: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

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

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

答案 2 :(得分:3)

plyr非常容易:

library(plyr)
ddply(df, .(Category),
      function (d) {
        d$Growth <- c(NA, tail(d$Value, -1) / head(d$Value, -1) - 1)
        d
      }
)

我们在这里有两个问题:

  1. 按类别划分
  2. 计算增长率
  3. ddply是主力,分裂和计算增长率的函数由此函数的参数定义。

答案 3 :(得分:2)

基于Ben的想法使用my R package中新的gdiff函数的更优雅的变体:

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, kimisc::gdiff(Value, FUN = `/`)-1))

此处,gdiff用于计算滞后率(而非diff所示的滞后差异。)

答案 4 :(得分:0)

很多年后:tsbox软件包旨在与各种时间序列对象(包括数据帧)一起使用,并提供标准的时间序列工具包。因此,计算增长率很简单:

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

library(tsbox)
ts_pc(df)
#> [time]: 'Year' [value]: 'Value' 
#>    Category       Year      Value
#> 1         A 2010-01-01         NA
#> 2         A 2011-01-01 100.000000
#> 3         A 2012-01-01  50.000000
#> 4         A 2013-01-01  33.333333
#> 5         A 2014-01-01  25.000000
#> 6         A 2015-01-01  20.000000
#> 7         B 2010-01-01         NA
#> 8         B 2011-01-01  14.285714
#> 9         B 2012-01-01  12.500000
#> 10        B 2013-01-01  11.111111
#> 11        B 2014-01-01  10.000000
#> 12        B 2015-01-01   9.090909

答案 5 :(得分:0)

CRAN中提供的软件包collapse为此类问题提供了一种简单且完全基于C / C ++的解决方案:通用函数fgrowth和相关的增长算子G:< / p>

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

library(collapse)
G(df, by = ~Category, t = ~Year)

   Category Year   G1.Value
1         A 2010         NA
2         A 2011 100.000000
3         A 2012  50.000000
4         A 2013  33.333333
5         A 2014  25.000000
6         A 2015  20.000000
7         B 2010         NA
8         B 2011  14.285714
9         B 2012  12.500000
10        B 2013  11.111111
11        B 2014  10.000000
12        B 2015   9.090909

# fgrowth is more of a programmers function, you can do:

fgrowth(df$Value, 1, 1, df$Category, df$Year)
 [1]   NA 100.000000  50.000000  33.333333  25.000000  20.000000         NA  14.285714  12.500000  11.111111  10.000000   9.090909

# Which means: Calculate the growth rate of Value, using 1 lag, and iterated 1 time (you can compute arbitrary sequences of lagged / leaded and iterated growth rates with these functions), identified by Category and Year.

fgrowth / G在plm软件包中还提供了plm::pseriesplm::pdata.frame类的方法。

答案 6 :(得分:-1)

您可以简单地使用dplyr软件包:

> df %>% group_by(Category) %>% mutate(Growth = (Value - lag(Value))/lag(Value))  

将产生以下结果:

# 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