数据结构如下......
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
答案 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
}
)
我们在这里有两个问题:
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::pseries
和plm::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