Как рассчитать темпы роста в формате длинного формата?
С данными, структурированными следующим образом...
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
Ответы
Ответ 1
Для таких вопросов ( "как я могу вычислить XXX по категории YYY" )? всегда существуют решения на основе 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])
для всех 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]
). ОР хотел, чтобы дробное изменение, а не мультипликативная скорость роста (т.е. x[t+1]==x[t]
соответствует дробному изменению нуля, а не мультипликативной скорости роста 1,0), поэтому мы вычитаем 1.
Я также использую transform()
для немного дополнительного "синтаксического сахара", чтобы избежать создания новой анонимной функции.
Ответ 2
Использование базовой функции 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)))
Ответ 3
Очень легко с plyr
:
library(plyr)
ddply(df, .(Category),
function (d) {
d$Growth <- c(NA, tail(d$Value, -1) / head(d$Value, -1) - 1)
d
}
)
Здесь у нас две проблемы:
- Разделение по категориям
- Вычисление темпа роста
ddply
- рабочая лошадка, разделение и функция для вычисления скорости роста определяются параметрами этой функции.
Ответ 4
Более элегантный вариант, основанный на идее Бена с новой функцией gdiff
в мой пакет R:
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
).
Ответ 5
Вы можете просто использовать пакет 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
Ответ 6
Спустя много лет: пакет 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