【问题标题】:sfLapply & apply.rolling on a xts object - Resulting Error: subscript out of boundssfLapply & apply.rolling 在 xts 对象上 - 导致错误:下标超出范围
【发布时间】:2015-12-10 07:39:33
【问题描述】:

我的目标是使用相同的数据结构将 5 只股票(xts 对象)的每日回报映射到 90 天回顾期的滚动标准差(计算过去 90 天回报的 SD),并且速度快。使用核心功能“lapply”的方法效果很好。但是,由于某些原因,降雪包中的并行方法“sfLapply”不起作用。这是插图:

初始化库并模拟数据集和参数:

require(PerformanceAnalytics)
require(quantmod)
require(snowfall)

adjReturns <- replicate(5, rnorm(10000, mean = 0.01, sd = 0.008))
colnames(adjReturns) <- c('stock1','stock2','stock3','stock4','stock5')
timeIndex <- seq.Date(as.Date("2015-01-01", "%Y-%m-%d"), by ="day", length.out = 10000)
adjReturns <- as.xts(adjReturns, order.by = timeIndex)

使用 lapply 计算滚动 SD 得到一个可行的解决方案:

rollingSD <- list()
rollingSD <- lapply(adjReturns, function(x) apply.rolling(x, width = 90, FUN = "sd"))
rollingSD <- do.call(cbind, rollingSD)

这里是并行版本,不起作用:

sfInit(parallel = TRUE, cpus = 4, type = "SOCK", socketHosts = rep("localhost", 2))
sfLibrary(snowfall)
sfLibrary(PerformanceAnalytics)
sfLibrary(xts)
sfLibrary(quantmod)
sfExportAll()

rollingSDSnow <- list()
rollingSDSnow <- sfLapply(adjReturns, function(x) apply.rolling(x, width = 90, FUN = "sd"))
rollingSDSnow <- do.call(cbind, rollingSDSnow)

sfStop()

上面的代码返回如下错误:

Error in `[.xts`(x, i) : subscript out of bounds

我不确定为什么会出现这个错误,因为我什至没有编写自己的 for 循环。请指出任何可能的错误,任何想法将不胜感激并感谢您的帮助!

环境: R:3.2.0/ RStudio:0.99.472 / 雪:0.3-13 / 降雪:1.84-6/ xts:0.9-7/ PerfomanceAnalytics:1.4.3541

附:可以使用 runSD 代替 apply.rolling,使用 apply.rolling 是因为它可以使用不同的功能。

【问题讨论】:

    标签: r xts snow performanceanalytics snowfall


    【解决方案1】:

    这是traceback

    > rollingSDSnow <- sfLapply(adjReturns, function(x) apply.rolling(x, 90, FUN = sd))
    Error in `[.xts`(x, i) : subscript out of bounds
    > traceback()
    13: stop("subscript out of bounds")
    12: `[.xts`(x, i)
    11: x[i]
    10: FUN(X[[i]], ...)
    9: lapply(splitIndices(length(x), ncl), function(i) x[i])
    8: splitList(x, length(cl))
    7: staticClusterApply(cl, fun, length(x), argfun)
    6: clusterApply(cl, splitList(x, length(cl)), lapply, fun, ...)
    5: lapply(args, enquote)
    4: do.call("fun", lapply(args, enquote))
    3: docall(c, clusterApply(cl, splitList(x, length(cl)), lapply, 
           fun, ...))
    2: parLapply(sfGetCluster(), x, fun, ...)
    1: sfLapply(adjReturns, function(x) apply.rolling(x, 90, FUN = sd))
    

    splitList 函数失败了。它失败了,因为它需要一个列表(sfLapply 中的“L”),但您传递了一个 xts 对象。 xts 对象的length 是观察次数,x[i] 尝试返回 xts 对象的第i 行,其中i 可能是nrow(x)*ncol(x),超出范围。


    解决方案是改用sfApply(我将使用runSD,因为我不想等待apply.rolling 完成运行)。

    rollingSD <- list()
    rollingSD <- lapply(adjReturns, runSD, n=90)
    rollingSD <- do.call(cbind, rollingSD)
    
    sfInit(parallel = TRUE, cpus = 4, type = "SOCK", socketHosts = rep("localhost", 2))
    sfLibrary(snowfall)
    sfLibrary(quantmod)
    sfExportAll()
    rollingSDSnow <- list()
    rollingSDSnow <- sfApply(adjReturns, 2, runSD, n=90)
    rollingSDSnow <- xts(rollingSDSnow, index(adjReturns))
    sfStop()
    
    all.equal(rollingSDSnow, rollingSD)
    # [1] TRUE
    

    【讨论】:

    • 感谢 Joshua 编写了超快速的 runSD 函数并提供了如此大的帮助! (当我有更多权限时会投票给帖子!)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    相关资源
    最近更新 更多