使用包含月度数据的n年时间序列计算季节性均值

时间:2016-12-20 03:10:49

标签: r dataframe

我有一个包含3列(月,年,值)的数据帧df。

>head(df)
        months year   value
      January  01 23875.00
     February  01 15343.25
        March  01  9584.25
        April  01 19026.33
          May  01 26324.00
         June  01 31228.00

每12行(从1月1日开始),年份为02,03,04等,直到16。 我需要计算季节性手段,即 夏季平均值(12月,1月,2月);秋季平均值(3月,4月,5月),冬季平均值(6月,7月,8月)和春季均值(9月,10月,11月)。

然后创建一个包含季节,年份和平均值的新数据框,以获得类似的结果。

>head(seasdf)
season year value
 DJF   01    
 MAM   01    
 JJA   01    
 SON   01    
 DJF   02    
 MAM   02    

这些年来一直到16岁。我用这种数据框搜索了类似的问题,但我找不到办法。

抱歉这个noob问题。

2 个答案:

答案 0 :(得分:3)

我们假设同一季度的相邻月份应该具有相同的季度名称和年份,并且该季度以季度结束的年份命名。例如,2001年12月,2002年1月和2002年2月都将成为DJF 2002季度的一部分。

首先将年份和月份转换为"yearmon"类变量ym,然后添加1/12以将月份推向前一个。这是基于以下事实:将yearmon变量存储为Jan的年份+ 0,2月的1/12,Mar的2/12,等等。然后将其转换为"yearqtr"类变量{{1} }。现在通过yq汇总value,注意yearqtr变量正确排序,以便2001 Q1将在2001年Q2之前出现,等等。最后使用问题中显示的列重新构建聚合数据框。

yq

,并提供:

library(zoo)  # yearmon and yearqtr classes

ym <- as.yearmon(paste(DF$months, DF$year), "%B %y")
yq <- as.yearqtr(ym + 1/12)

Ag <- aggregate(value ~ yq, DF, mean)

season.name <- c("DJF", "MAM", "JJA", "SON")
with(Ag, data.frame(year = as.integer(yq), season = season.name[cycle(yq)], value))

如果问题中显示的确切布局不重要,那么我们可以省略上面最后两行代码,只使用 year season value 1 2001 DJF 19609.12 2 2001 MAM 18311.53 3 2001 JJA 31228.00

Ag

注意:可重复形式的输入> Ag yq value 1 2001 Q1 19609.12 2 2001 Q2 18311.53 3 2001 Q3 31228.00 被假定为:

DF

答案 1 :(得分:2)

似乎您的months变量是标准月份名称,您可以将其与R中的month.name变量匹配,以将月份作为数字,即(1月将为1,2月将为2,等等,并采用3的模除法将季节作为除year之外的另一组变量,然后按年份,季节分组并取平均值应该是微不足道的:

library(dplyr)
df %>% group_by(season = match(months, month.name) %% 12 %/% 3, year) %>% 
       summarise(value = mean(value)) %>% ungroup() %>% 

       # optional: convert the season from number to meaningful labels which could also be 
       # summer, autumn, winter and spring
       mutate(season = factor(season, levels = c(0,1,2,3), 
                                      labels = c("DJF", "MAM", "JJA", "SON")))

# A tibble: 3 × 3
#  season  year    value
#  <fctr> <int>    <dbl>
#1    DJF     1 19609.12
#2    MAM     1 18311.53
#3    JJA     1 31228.00

如果12月需要滚动到明年夏天,您可以在year时向months == "December"变量添加一个:

df %>% group_by(season = match(months, month.name) %% 12 %/% 3, year = ifelse(months == "December", year + 1, year)) %>% 
       summarise(value = mean(value)) %>% ungroup() %>% 

       # optional: convert the season from number to meaningful labels which could also be 
       # summer, autumn, winter and spring
       mutate(season = factor(season, levels = c(0,1,2,3), 
                              labels = c("DJF", "MAM", "JJA", "SON")))