数据结构如下......
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()一些额外的"语法糖",以避免创建一个新的匿名函数.
使用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)