【问题标题】:Using Rollapply on two columns在两列上使用 Rollapply
【发布时间】:2010-12-25 09:11:57
【问题描述】:

我正在尝试做类似我要求 here 的事情,但不幸的是我无法解决。

这是我的数据框(data),价格的时间序列:

Date          Price   Vol
1998-01-01     200      0.3
1998-01-02     400      0.4
1998-01-03     600     -0.2
1998-01-04     100      0.1
...
1998-01-20     100      0.1
1998-01-21     200     -0.4
1998-01-21     500      0.06
....
1998-02-01     100      0.2
1998-02-02     200      0.4
1998-02-03     500      0.3
1998-02-04     100      0.1
etc.

我想告诉R,给

  • 取“Vol”的第 1 个值除以“Price”的第 20 个值,然后
  • 取“Vol”的第 2 个值除以“Price”的第 21 个值。
  • 取“Vol”的第 3 个值除以“Price”的第 22 个值,然后

在我的另一篇文章中,我能够使用此函数计算 20 天持有期的回报:

> data.xts <- xts(data[, -1], data[, 1])
> hold <- 20
> f <- function(x) log(tail(x, 1)) - log(head(x, 1))
> data.xts$returns.xts <- rollapply(data.xts$Price, FUN=f, 
  width=hold+1, align="left", na.pad=T)

有没有办法为上述问题做一些非常相似的事情?所以像

f1 <- function(x,y) head(x, 1) / tail(y,1)

其中 x 是“Vol”,y 是“Price”,然后应用“rollapply”?

非常感谢

更新:@G 博士: 感谢您的建议。稍作改动,它就如我所愿!

data.xts <- xts(data[, -1], data[, 1])
hold <- 20
data.xts$quo <- lag(data.xts[,2], hold) / data.xts[,1]

现在我的问题是,生成的数据框如下所示:

    Date          Price   Vol     quo
1 1998-01-01     200      0.3     NA
2 1998-01-02     400      0.4     NA
3 1998-01-03     600     -0.2     NA
4 1998-01-04     100      0.1     NA
...
21 1998-01-20    180      0.2     0.003 

我知道必须有 NA 作为结果,但仅限于最后 20 次观察,而不是前 20 次观察。上述公式计算了正确的值,但它们从第 21 行而不是第一行开始。你知道我怎么能改变它吗?

【问题讨论】:

  • 对于你的后续问题,你不能用 lag(quo, -hold) 将 quo 向后移动。没有例子就未经测试,因为格洛腾迪克是迄今为止唯一的一个,所以我担心滞后的标志可能需要切换。

标签: r time-series xts zoo


【解决方案1】:

rollapply 中使用by.column = FALSE。为了使用发布的数据,我们将第一行中的交易量除以第三行中的价格,以此类推,以便重现说明:

library(zoo)

Lines <- "Date          Price   Vol
1998-01-01     200      0.3
1998-01-02     400      0.4
1998-01-03     600     -0.2
1998-01-04     100      0.1
1998-01-20     100      0.1
1998-01-21     200     -0.4
1998-01-21     500      0.06
1998-02-01     100      0.2
1998-02-02     200      0.4
1998-02-03     500      0.3
1998-02-04     100      0.1"


# read in and use aggregate to remove all but last point in each day.
# In reality we would replace textConnection(Lines) with something 
#  like "myfile.dat"

z <- read.zoo(textConnection(Lines), header = TRUE, 
       aggregate = function(x) tail(x, 1))

# divide Volume by the Price of the point 2 rows ahead using by.column = FALSE
# Note use of align = "left" to align with the volume.
# If we used align = "right" it would align with the price.

rollapply(z, 3, function(x) x[1, "Vol"] / x[3, "Price"], by.column = FALSE,
    align = "left")

# and this is the same as rollapply with align = "left" as above
z$Vol / lag(z$Price, 2)

# this is the same as using rollapply with align = "right"
lag(z$Vol, -2) / z$Price

顺便说一下,请注意zoo 使用与R 相同的lag 符号约定,但xts 使用相反的约定,因此如果您将上述转换为xts,您将不得不消除滞后。

【讨论】:

    【解决方案2】:

    实际上比这更容易。只需这样做:

    data.xts <- xts(data[, -1], data[, 1])
    hold <- 20
    returns.xts = data.xts[,2] / lag(data.xts[,1], hold)
    

    实际上,使用 zoo 而不是 xts 也可以:

    data.zoo<- zoo(data[, -1], data[, 1])
    hold <- 20
    returns.zoo = data.zoo[,2] / lag(data.zoo[,1], -hold)
    

    唯一改变的是滞后的迹象(动物园惯例与 xts 不同)

    【讨论】:

    • 酷,我不得不做一个小改动,并且计算的值是正确的。由于一个新问题,我更新了我的 Q。你有什么主意吗?谢谢!
    【解决方案3】:

    你只需要使用

    data.xts$quo <- data.xts[,2] / lag( data.xts[,1], -hold)
    

    【讨论】:

      猜你喜欢
      • 2016-02-22
      • 2014-02-15
      • 2018-01-21
      • 2012-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多