R 中 apply.monthly 的每月操作时间序列

Monthly operations time series with apply.monthly in R

问题是使用 apply.monthly 或任何其他类似函数对数据集进行每月操作。我的数据如下所示:

> minidata[1:10,]
          date Month Year TMIN
 1  1948-01-01   Jan 1948  1.1
 2  1948-01-02   Jan 1948  7.2
 3  1948-01-03   Jan 1948  5.0
 4  1948-01-04   Jan 1948  9.4
 5  1948-01-05   Jan 1948  4.4

 > tail(minidata)
     date      Month Year TMIN
 54 1948-02-23   Feb 1948  2.8
 55 1948-02-24   Feb 1948 -0.6
 56 1948-02-25   Feb 1948  1.7
 57 1948-02-26   Feb 1948  2.8
 58 1948-02-27   Feb 1948  4.4
 59 1948-02-28   Feb 1948  3.3

任务,使用我自己的函数生成月均值:

 mymean <- function(date){
   for (j in 1:days_in_month(date)){
     avg = (1/(days_in_month(date))
           *sum(minidata$TMIN[1:days_in_month(date)])}
   return(avg)
 }

结果必须与xts包中的R函数相同:

 dat.xts <- xts(x= minidata$TMIN,order.by = minidata$date)
 > apply.monthly(dat.xts,mean)
                [,1]
 1948-01-31 2.312903
 1948-02-28 2.082143

我的函数输出正确的值:

 > mymean(minidata$date[1])
      Jan 
 2.312903 
 > mymean(dat.xts[1])
      Jan 
 2.312903

我不介意 $apply.monthly$ 用这个方法生成一个新列,但我必须使用我自己的函数! (这是一个例子,实际上我的功能要难得多)。

我试过了:

 > apply.monthly(dat.xts,function(dat.xts) mymean(dat.xts))
 Error in coredata.xts(x) : currently unsupported data type
 In addition: There were 50 or more warnings (use warnings() to see the first 50)

谢谢!

更新:days_in_month 可以在 lubridate 包中找到。它计算给定月份的天数

要在数据框的组内执行操作,您可以使用 dplyr 包。例如,要获得每个组内的平均值 TMIN

library(dplyr)
summarize(group_by(minidata, Month), mean = mean(TMIN))

这通常写成:

minidata %>% group_by(Month) %>%
    summarize(mean = mean(TMIN))

您的函数仅适用于数据框,xts 对象不同,不会按您希望的方式工作。这就是为什么它给你错误。

除此之外,您不想使用循环执行此操作。这将比许多其他方法花费更长的时间。

David 的回答(使用 dplyr::group_bydplyr::summarize)是处理此问题的最佳方法。如果这是问题所在,您可以在 summarize 中使用自定义函数。只需定义您的功能并在那里使用它。

问题是你的功能,而不是 apply.monthly。我不知道 days_in_month 函数在哪里定义,但它可能不适用于 xts 对象。我假设它需要一个日期时间 class.

并且您的 mymean 函数引用了一个未传递给它的对象,这不是好的做法,因为它会使 R 搜索 minidata.

您的函数应该期望包含一个月数据的 xts 对象,并且仅对该数据进行操作,而不是函数范围之外的某些对象。例如:

mymean <- function(Data) {
  days <- days_in_month(index(Data)[1])
  avg <- (1/days) * sum(Data$Close)
  return(avg)
}
require(xts)
data(sample_matrix)
x <- as.xts(sample_matrix)
apply.monthly(x, mymean)