如何计算R中每日时间序列的月变化率?

时间:2013-07-18 17:36:20

标签: r time-series xts zoo

我开始用R弄湿自己,我对时间序列概念不熟悉。任何人都可以指出我正确的方向来计算每月的%变化,基于每日数据点?我想要在每个月的第一个和最后一个数据点之间进行更改。例如:

tseries数据:

1/1/2000 10.00
...
1/31/2000 10.10
2/1/2000 10.20
...
2/28/2000 11.00

我正在寻找以下形式的返回数据框:

1/31/2000 .01
2/28/2000 .0784

理想情况下,我能够从上个月的终点计算到当月的终点,但我认为按月分区更容易作为起点。我正在看包裹动物园和xts,但我仍然卡住了。任何接受者?感谢...

5 个答案:

答案 0 :(得分:2)

以下是使用plyrddply执行此操作的一种方法。 我按顺序使用ddply,首先获取每个月的第一行和最后一行,然后再次计算 monthlyReturn。 (也许使用xts或动物园可能会更容易,我不确定。)

#Using plyr and the data in df
df$Date <- as.POSIXlt(as.Date(df$Date, "%m/%d/%Y"))
df$Month <- (df$Date$mon + 1) #0 = January

sdf <- df[,-1] #drop the Date Column, ddply doesn't like it

library("plyr")
#this function is called with 2 row data frames
monthlyReturn<- function(df) {
  (df$Value[2] - df$Value[1])/(df$Value[1])  
}

adf <- ddply(sdf, .(Month), function(x) x[c(1, nrow(x)), ]) #get first and last values for each Month   
mon.returns <- ddply(adf, .(Month), monthlyReturn)

以下是我用来测试它的数据:

> df
         Date Value
1    1/1/2000  10.0
2   1/31/2000  10.1
3    2/1/2000  10.2
4   2/28/2000  11.0
5    3/1/2000  10.0
6   3/31/2000  24.1
7   5/10/2000 510.0
8   5/22/2000 522.0
9   6/04/2000 604.0
10  7/03/2000  10.1
11  7/30/2000   7.2
12 12/28/2000  11.0
13 12/30/2000   3.0

> mon.returns
  Month          V1
1     1  0.01000000
2     2  0.07843137
3     3  1.41000000
4     5  0.02352941
5     6  0.00000000
6     7 -0.28712871
7    12 -0.72727273

希望有所帮助。

答案 1 :(得分:1)

这是另一种方法(使用quantmod包):

这将计算AAPL每日价格的月度回报。

*library(quantmod)     # load the quantmod package
getSymbols("AAPL")     # download daily price for stock AAPL
monthlyReturn = periodReturn(AAPL,period="monthly")
monthlyReturn2014 = periodReturn(AAPL,period="monthly",subset='2014:') # for 2014*

答案 2 :(得分:1)

这是一个非常古老的主题,但作为参考,这里有一个使用@Ram相同数据的data.table解决方案:

structure(list(Date = structure(c(10957, 10987, 10988, 11015, 11017, 11047, 11087, 11099, 11112, 11141, 11168, 11319, 11321), class = "Date"), Value = c(10, 10.1, 10.2, 11, 10, 24.1, 510, 522, 604, 10.1, 7.2, 11, 3)), .Names = c("Date", "Value"), row.names = c(NA, -13L), class = c("data.table", "data.frame"), .internal.selfref = <pointer: 0x00000000001b0788>)

它本质上是一个使用data.table::month函数的单行程序:

library(data.table)

setDT(df)[ , diff(Value) / Value[1], by= .(month(Date))]

这将产生相对于每个月的第一个记录日的变化。如果首选相对于最后日的更改,则应将中间的表达式更改为diff(Value) / Vale[2]

答案 3 :(得分:1)

1)没有套餐试试这个:

DF <- read.table(text = Lines)

fmt <- "%m/%d/%Y"
ym <- format(as.Date(DF$V1, format = fmt), "%Y-%m")

ret <- function(x) diff(range(x))/x[1]
ag <- aggregate(V2 ~ ym, DF, ret)

,并提供:

> ag
       ym         V2
1 2000-01 0.01000000
2 2000-02 0.07843137

如果需要,我们可以将其转换为"ts"类。假设没有错过的月份:

ts(ag$V2, start = 2000, freq = 12)

,并提供:

            Jan        Feb
2000 0.01000000 0.07843137

2)如果您使用zoo或xts时间序列包,它会更容易一些。 fmtret来自上方:

library(zoo)
z <- read.zoo(text = Lines, format = fmt)
z.ret <- aggregate(z, as.yearmon, ret)

,并提供:

> z.ret
  Jan 2000   Feb 2000 
0.01000000 0.07843137 

如果您已有data.frame DF,那么read.zoo语句可以替换为z <- read.zoo(DF, format = fmt),如果第一列是{{format,则省略"Date" arg 1}} class。

如果需要"ts"课程,请使用as.ts(z.ret)

注意:输入Lines为:

Lines <- "1/1/2000 10.00
1/31/2000 10.10
2/1/2000 10.20
2/28/2000 11.00"

答案 4 :(得分:0)

TTR包中的ROC功能将执行此操作。如果您只关注月度行为,则可以先使用to.monthly或endpoints()(From daily time series to weekly time series in R xts object)。

library(TTR)
# data.monthly <- to.monthly( data, indexAt='periodEnd' ) # if OHLC data
# OR
data.monthly <- data[ endpoints(data, on="months", k=1), ]
data.roc <- ROC(data.monthly, n = 1, type = "discrete")