2015-06-06 15 views
15

Próbowałem obliczyć tempo wzrostu porównując kwartał 1 z jednego roku do pierwszego kwartału na następny rok.
W programie Excel formuła wyglądałaby tak ((B6-B2)/B2) * 100.Kwartalna roczna stopa wzrostu gospodarczego

Jaki jest najlepszy sposób na osiągnięcie tego w R? Wiem, jak uzyskać różnice między poszczególnymi okresami, ale nie mogę tego osiągnąć z 4-dniową różnicą czasową.

Oto kod:

date <- c("2000-01-01","2000-04-01", "2000-07-01", 
      "2000-10-01","2001-01-01","2001-04-01", 
      "2001-07-01","2001-10-01","2002-01-01", 
      "2002-04-01","2002-07-01","2002-10-01") 
value <- c(1592,1825,1769,1909,2022,2287,2169,2366,2001,2087,2099,2258) 
df <- data.frame(date,value) 

która będzie produkować tę ramkę danych:

date  value 
1 2000-01-01 1592 
2 2000-04-01 1825 
3 2000-07-01 1769 
4 2000-10-01 1909 
5 2001-01-01 2022 
6 2001-04-01 2287 
7 2001-07-01 2169 
8 2001-10-01 2366 
9 2002-01-01 2001 
10 2002-04-01 2087 
11 2002-07-01 2099 
12 2002-10-01 2258 

Odpowiedz

7

Oto bardzo proste rozwiązanie:

YearOverYear<-function (x,periodsPerYear){ 
    if(NROW(x)<=periodsPerYear){ 
     stop("too few rows") 
    } 
    else{ 
     indexes<-1:(NROW(x)-periodsPerYear) 
     return(c(rep(NA,periodsPerYear),(x[indexes+periodsPerYear]-x[indexes])/x[indexes])) 
    } 
} 


> cbind(df,YoY=YearOverYear(df$value,4)) 
     date value   YoY 
1 2000-01-01 1592   NA 
2 2000-04-01 1825   NA 
3 2000-07-01 1769   NA 
4 2000-10-01 1909   NA 
5 2001-01-01 2022 0.27010050 
6 2001-04-01 2287 0.25315068 
7 2001-07-01 2169 0.22611645 
8 2001-10-01 2366 0.23939235 
9 2002-01-01 2001 -0.01038576 
10 2002-04-01 2087 -0.08745081 
11 2002-07-01 2099 -0.03227294 
12 2002-10-01 2258 -0.04564666 
12

Oto opcja przy użyciu pakietu dplyr:

# Convert date column to date format 
df$date = as.POSIXct(df$date) 

library(dplyr) 
library(lubridate) 

W poniższym kodzie, najpierw grupujemy według miesięcy, co pozwala nam działać oddzielnie w każdym kwartale. Funkcja arrange zapewnia tylko, że dane w każdym kwartale są uporządkowane według daty. Następnie dodajemy kolumnę yearOverYear przy użyciu mutate, która oblicza stosunek bieżącego roku do poprzedniego roku dla każdego kwartału.

df = df %>% group_by(month=month(date)) %>% 
    arrange(date) %>% 
    mutate(yearOverYear=value/lag(value,1)) 

     date value month yearOverYear 
1 2000-01-01 1592  1   NA 
2 2001-01-01 2022  1 1.2701005 
3 2002-01-01 2001  1 0.9896142 
4 2000-04-01 1825  4   NA 
5 2001-04-01 2287  4 1.2531507 
6 2002-04-01 2087  4 0.9125492 
7 2000-07-01 1769  7   NA 
8 2001-07-01 2169  7 1.2261164 
9 2002-07-01 2099  7 0.9677271 
10 2000-10-01 1909 10   NA 
11 2001-10-01 2366 10 1.2393924 
12 2002-10-01 2258 10 0.9543533 

Jeśli wolisz mieć ramkę danych z powrotem w ogólnej data po dodaniu rok do roku wartości:

df = df %>% group_by(month=month(date)) %>% 
    arrange(date) %>% 
    mutate(yearOverYear=value/lag(value,1)) %>% 
    ungroup() %>% arrange(date) 

lub używając data.table

library(data.table) # v1.9.5+ 
setDT(df)[, .(date, yoy = (value-shift(value))/shift(value)*100), 
      by = month(date) 
     ][order(date)] 
+0

Dziękujemy za odpowiedź! Bardzo doceniane. – Wolf

5
df$yoy <- c(rep(NA,4),(df$value[5:nrow(df)]-df$value[1:(nrow(df)-4)])/df$value[1:(nrow(df)-4)]*100); 
df; 
##   date value  yoy 
## 1 2000-01-01 1592  NA 
## 2 2000-04-01 1825  NA 
## 3 2000-07-01 1769  NA 
## 4 2000-10-01 1909  NA 
## 5 2001-01-01 2022 27.010050 
## 6 2001-04-01 2287 25.315068 
## 7 2001-07-01 2169 22.611645 
## 8 2001-10-01 2366 23.939235 
## 9 2002-01-01 2001 -1.038576 
## 10 2002-04-01 2087 -8.745081 
## 11 2002-07-01 2099 -3.227294 
## 12 2002-10-01 2258 -4.564666 
+0

Dziękuję bardzo. Bardzo prosty sposób! – Wolf

2

Kolejne rozwiązanie bazowe R. Wymaga to, że data jest w formacie daty, tak, że wspólne miesięcy mogą być używane jako zmiennej grupującej do którego funkcja obliczania tempa wzrostu mogą być przekazywane

# set date to a date objwct 
df$date <- as.Date(df$date) 

# order by date 
df <- df[order(df$date), ] 

# function to calculate differences 
f <- function(x) c(NA, 100*diff(x)/x[-length(x)]) 

df$yoy <- ave(df$value, format(df$date, "%m"), FUN=f) 
#   date value  yoy 
# 1 2000-01-01 1592  NA 
# 2 2000-04-01 1825  NA 
# 3 2000-07-01 1769  NA 
# 4 2000-10-01 1909  NA 
# 5 2001-01-01 2022 27.010050 
# 6 2001-04-01 2287 25.315068 
# 7 2001-07-01 2169 22.611645 
# 8 2001-10-01 2366 23.939235 
# 9 2002-01-01 2001 -1.038576 
# 10 2002-04-01 2087 -8.745081 
# 11 2002-07-01 2099 -3.227294 
# 12 2002-10-01 2258 -4.564666 

lub

c(rep(NA, 4,), 100* diff(df$value, lag=4)/head(df$value, -4)) 
+1

Dziękuję za odpowiedź! – Wolf

Powiązane problemy