【问题标题】:assign new column for xts为 xts 分配新列
【发布时间】:2013-02-25 23:31:13
【问题描述】:

我已经使用lapply 将累积产品计算为数据集上的新列,但我必须获取数据,计算它,然后在 lapply 的每次迭代中使用 assign 覆盖原始数据。我想知道是否有一种更优雅的方法可以自动将新列名分配给 xts 对象

这是一个产生正确结果的模拟示例......它应该可以复制粘贴到 R

library(xts)
x <- xts(matrix(rnorm(10*1000,0.001,0.0001),ncol=10), Sys.Date()-c(1000:1))
colnames(x) <- paste0("x.",c(1:10))
tmp <- lapply(5:20, function(y){
    tmp.cum.prod <- rollapply(x,width=y,function(z){
        prod(rowMeans(z[,1:10])+1)-1
    },by.column=FALSE,align="right")
    orig.colnames <- colnames(x)
    x <- merge(x,tmp.cum.prod)
    colnames(x) <- c(orig.colnames,paste0("cum.prod.",y))
    assign("x",x,envir=.GlobalEnv)
})
tail(x)

但我认为可能会改进以下几行:

orig.colnames <- colnames(x)
x <- merge(x,tmp.cum.prod)
colnames(x) <- c(orig.colnames,paste0("cum.prod.",y))
assign("x",x,envir=.GlobalEnv)

有什么建议吗?另外,如果您认为上面还有其他可以改进的行(例如使用lapply),我总是热衷于学习如何编写更优雅的代码。

谢谢

【问题讨论】:

    标签: r xts zoo


    【解决方案1】:

    如果您在 lapply 函数中分配给全局环境,您可能应该使用 for 循环。这就是我会做的......

    set.seed(21)
    x <- xts(matrix(rnorm(10*1000,0.001,0.0001),ncol=10), Sys.Date()-1000:1)
    colnames(x) <- paste0("x.",1:10)
    
    rmx <- xts(rowMeans(x)+1,index(x))
    for(i in 5:20) {
      tmp.cum.prod <- rollapplyr(rmx,i,prod,by.column=FALSE)-1
      colnames(tmp.cum.prod) <- paste0("cum.prod.",i)
      x <- merge(x,tmp.cum.prod)
    }
    

    【讨论】:

    • 在您看来,分配给全局环境是使用for 循环而不是lapply 的主要原因吗?
    • 这是一个很大的原因。无论如何,您只是将lapply 用作循环(即您不使用它创建的tmp 对象)。对于较大的对象,for 循环也可能会更快,因为您没有存储您创建的所有中间数据。
    • 哦,好吧...有趣的是,我一直假设 for 循环比 lapply 占用更多的内存,因此平均而言 lapply 往往更快(这是真的吗?) ,所以可能已经养成了如果有疑问选择lapply的习惯,但下次肯定会考虑到全球环境的分配。我想也更频繁地使用 lapply 意味着如果需要升级到 mclapply 升级它并不是一件太烦人的任务......
    • 我从未听过有人说 for 循环使用的内存比 lapply 多。 R 中的循环并不是特别慢,但人们之所以有这个想法,是因为他们在 内部 执行缓慢的循环(例如 data.frame 子集、附加到对象等)。如果您将lapply 用于更改现有对象的副作用,则应使用for 循环。如果要将函数应用于列表的每个元素,请使用 lapply
    【解决方案2】:

    您可以使用Reduce 来完成所有merge 而不是循环。

    > library(xts)
    > x <- xts(matrix(rnorm(10*1000,0.001,0.0001),ncol=10), Sys.Date()-c(1000:1))
    > colnames(x) <- paste0("x.",c(1:10))
    > tmp <- lapply(5:20, function(y){
    +   tmp.cum.prod <- rollapply(x,width=y,function(z){
    +     prod(rowMeans(z[,1:10])+1)-1
    +   },by.column=FALSE,align="right")
    +   colnames(tmp.cum.prod) <- paste0("cum.prod.",y)
    +   return(tmp.cum.prod)
    + })
    > 
    > result <- Reduce(function(...) merge(..., all=F), tmp, init = x)
    > tail(result)
                        x.1          x.2          x.3          x.4          x.5          x.6          x.7          x.8          x.9         x.10
    2013-02-20 0.0008919729 0.0010013599 0.0010276262 0.0007968856 0.0010731857 0.0010363689 0.0012281909 0.0010999609 0.0012081942 0.0010884836
    2013-02-21 0.0009690167 0.0009131937 0.0009831485 0.0011843868 0.0011380318 0.0010424227 0.0011061298 0.0009944692 0.0010294051 0.0009762645
    2013-02-22 0.0009269100 0.0010155799 0.0009445889 0.0010970406 0.0010646493 0.0011235968 0.0009402159 0.0010529831 0.0010884473 0.0008735272
    2013-02-23 0.0009855041 0.0008282001 0.0011063870 0.0010430884 0.0008031531 0.0012577790 0.0009949316 0.0010046824 0.0011176581 0.0010516397
    2013-02-24 0.0008176369 0.0009818399 0.0009964602 0.0009347190 0.0010362750 0.0010734247 0.0009749511 0.0010822521 0.0009335049 0.0010115921
    2013-02-25 0.0009861176 0.0007606129 0.0010802525 0.0008771646 0.0010292476 0.0009319029 0.0011008009 0.0007901849 0.0011368412 0.0009677856
                cum.prod.5  cum.prod.6  cum.prod.7  cum.prod.8  cum.prod.9 cum.prod.10 cum.prod.11 cum.prod.12 cum.prod.13 cum.prod.14 cum.prod.15
    2013-02-20 0.005080621 0.006084484 0.007080320 0.008074656 0.009105274  0.01009016  0.01111046  0.01212787  0.01317140  0.01416878  0.01516398
    2013-02-21 0.005127238 0.006119520 0.007124420 0.008121286 0.009116649  0.01014833  0.01113423  0.01215559  0.01317405  0.01421867  0.01521707
    2013-02-22 0.005119219 0.006145185 0.007138471 0.008144390 0.009142264  0.01013864  0.01117136  0.01215826  0.01318065  0.01420015  0.01524582
    2013-02-23 0.005120808 0.006143740 0.007170751 0.008165050 0.009171994  0.01017089  0.01116827  0.01220205  0.01318996  0.01421339  0.01523392
    2013-02-24 0.005105586 0.006110114 0.007134052 0.008162074 0.009157352  0.01016529  0.01116516  0.01216353  0.01319833  0.01418721  0.01521165
    2013-02-25 0.005026133 0.006076609 0.007082108 0.008107036 0.009136051  0.01013229  0.01114120  0.01214204  0.01314137  0.01417717  0.01516701
               cum.prod.16 cum.prod.17 cum.prod.18 cum.prod.19 cum.prod.20
    2013-02-20  0.01619964  0.01724359  0.01830398  0.01928576  0.02034408
    2013-02-21  0.01621330  0.01725003  0.01829506  0.01935654  0.02033935
    2013-02-22  0.01624524  0.01724248  0.01828025  0.01932634  0.02038890
    2013-02-23  0.01628066  0.01728110  0.01827936  0.01931819  0.02036534
    2013-02-24  0.01623318  0.01728095  0.01828237  0.01928161  0.02032147
    2013-02-25  0.01619243  0.01721496  0.01826374  0.01926613  0.02026633
    

    【讨论】:

      猜你喜欢
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-03
      • 1970-01-01
      • 1970-01-01
      • 2014-03-16
      • 1970-01-01
      相关资源
      最近更新 更多