移动平均线
Moving averages
我有 100 多年的每日数据,看起来像
01.01.1856 12
02.01.1956 9
03.01.1956 -12
04.01.1956 7
etc.
我想计算这个庞大数据的 30 年 运行 平均值。我尝试将数据转换为时间序列,但仍然无法弄清楚如何去做。我更喜欢使用 data.frame.
的简单方法
考虑到一些闰年,我想准备工作是困难的。
因此,在使用包 require(caTools)
中已经提到的函数 runmean
之前,我尝试展示一些准备方法。
首先我们创建示例数据(这对您来说不是必需的,但为了理解)。
其次,我将数据框分成一系列数据框,每年一个,并取每年的平均值。这两个步骤可以同时完成,但我认为分开的方式更容易理解和适应。
#example data
Days <- seq(as.Date("1958-01-01"), as.Date("2015-12-31"), by="days")
Values <- runif(length(Days))
DF <- data.frame(Days = Days, Values = Values)
#start of script
Years <- format(DF$Days, "%Y")
UniqueYears <- unique(format(DF$Days, "%Y"))
#Create subset of years
#look for every unique year which element of days is in this year.
YearlySubset <- lapply(UniqueYears, function(x){
DF[which(Years == x), ]
})
YearlyMeanValues <- sapply(YearlySubset, function(x){
mean(x$Values)
})
现在应用 运行 均值:
#install.packages("caTools")
require(caTools)
RM <- data.frame(Years = UniqueYears, RunningMean30y = runmean(YearlyMeanValues, 30))
如果我一开始没猜对你,而你想要在大约 30 年内的每一天都有一些 运行 平均值,当然你可以简单地做:
RM <- cbind(DF, runmean(DF$Values, 365 * 30))
考虑到您在创建时间序列时遇到的问题:
DF[ , 1] <- as.Date(DF[ , 1], format = "%Y.%m.%d")
我还建议探索 RcppRoll
与 dplyr
的结合,它提供了一个相当方便的解决方案来计算滚动平均值、总和等。
代码
# Libs
library(RcppRoll) # 'roll'-ing functions for R vectors and matrices.
library(dplyr) # data grammar (convenience)
library(zoo) # time series (convenience)
library(magrittr) # compound assignment pipe-operator (convenience)
# Data
data("UKgas")
## Convert to data frame to make example better
UKgas <- data.frame(Y = as.matrix(UKgas), date = time(UKgas))
# Calculations
UKgas %<>%
# To make example more illustrative I converted the data to a quarterly format
mutate(date = as.yearqtr(date)) %>%
arrange(date) %>%
# The window size can be changed to reflect any period
mutate(roll_mean = roll_mean(Y, n = 4, align = "right", fill = NA))
备注
由于示例中提供的数据相当有限,我使用了可通过 utils
包中的 data
函数获得的英国季度天然气消耗数据。
我有 100 多年的每日数据,看起来像
01.01.1856 12
02.01.1956 9
03.01.1956 -12
04.01.1956 7
etc.
我想计算这个庞大数据的 30 年 运行 平均值。我尝试将数据转换为时间序列,但仍然无法弄清楚如何去做。我更喜欢使用 data.frame.
的简单方法考虑到一些闰年,我想准备工作是困难的。
因此,在使用包 require(caTools)
中已经提到的函数 runmean
之前,我尝试展示一些准备方法。
首先我们创建示例数据(这对您来说不是必需的,但为了理解)。
其次,我将数据框分成一系列数据框,每年一个,并取每年的平均值。这两个步骤可以同时完成,但我认为分开的方式更容易理解和适应。
#example data
Days <- seq(as.Date("1958-01-01"), as.Date("2015-12-31"), by="days")
Values <- runif(length(Days))
DF <- data.frame(Days = Days, Values = Values)
#start of script
Years <- format(DF$Days, "%Y")
UniqueYears <- unique(format(DF$Days, "%Y"))
#Create subset of years
#look for every unique year which element of days is in this year.
YearlySubset <- lapply(UniqueYears, function(x){
DF[which(Years == x), ]
})
YearlyMeanValues <- sapply(YearlySubset, function(x){
mean(x$Values)
})
现在应用 运行 均值:
#install.packages("caTools")
require(caTools)
RM <- data.frame(Years = UniqueYears, RunningMean30y = runmean(YearlyMeanValues, 30))
如果我一开始没猜对你,而你想要在大约 30 年内的每一天都有一些 运行 平均值,当然你可以简单地做:
RM <- cbind(DF, runmean(DF$Values, 365 * 30))
考虑到您在创建时间序列时遇到的问题:
DF[ , 1] <- as.Date(DF[ , 1], format = "%Y.%m.%d")
我还建议探索 RcppRoll
与 dplyr
的结合,它提供了一个相当方便的解决方案来计算滚动平均值、总和等。
代码
# Libs
library(RcppRoll) # 'roll'-ing functions for R vectors and matrices.
library(dplyr) # data grammar (convenience)
library(zoo) # time series (convenience)
library(magrittr) # compound assignment pipe-operator (convenience)
# Data
data("UKgas")
## Convert to data frame to make example better
UKgas <- data.frame(Y = as.matrix(UKgas), date = time(UKgas))
# Calculations
UKgas %<>%
# To make example more illustrative I converted the data to a quarterly format
mutate(date = as.yearqtr(date)) %>%
arrange(date) %>%
# The window size can be changed to reflect any period
mutate(roll_mean = roll_mean(Y, n = 4, align = "right", fill = NA))
备注
由于示例中提供的数据相当有限,我使用了可通过 utils
包中的 data
函数获得的英国季度天然气消耗数据。