【问题标题】:How to apply a function to every consecutive n elements in a vector如何将函数应用于向量中的每个连续 n 元素
【发布时间】:2019-08-02 09:44:18
【问题描述】:

我正在尝试将季度回报转换为年度回报。给定一个季度回报向量,如何做到这一点?

我对 R 编程相当陌生,所以我还没有真正得到任何地方。

给定一个包含季度回报的向量a

a <- c(0.11, 0.02, 0.01, 0.1, 0.08, 0.04, 0.02, 0.03) # Two years worth of returns

我想应用一些函数,使用以下公式输出一个长度为 2 且具有年度回报的向量:

Year 1: ((1 + 0.11) * (1 + 0.02) * (1 + 0.01) * (1 + 0.1))-1  = 0,2578742
Year 2: ((1 + 0.08) * (1 + 0.04) * (1 + 0.02) * (1 + 0.03))-1 = 0,180033

最终向量:

yearly_vec <- c(0.2578742,  0.180033)

【问题讨论】:

    标签: r


    【解决方案1】:

    使用apply

    apply(matrix(a, nrow = 4), 2, function(x) prod(1 + x) - 1)
    #[1] 0.2578742 0.180033
    

    【讨论】:

    • apply(matrix(a+1, 4), 2, prod) - 1
    • @jogo 这样一个优雅的解决方案
    【解决方案2】:

    因为它们是季度回报,所以将向量分成 4 个组并计算每个组。

    tapply(a, gl(length(a)/4, 4), function(x) prod(1 + x) - 1)
    #    1      2 
    #0.2579 0.1800 
    

    分组部分和计算部分可以通过多种方式完成。例如,上面也可以使用split + sapply来完成

    sapply(split(a, gl(length(a)/4, 4)), function(x) prod(1 + x) - 1)
    

    或者也可以使用rep进行分组

    tapply(a,rep(seq_along(a), each = 4, length.out = length(a)), 
             function(x) prod(1 + x) - 1)
    

    【讨论】:

    • tapply(a+1, gl(length(a)/4, 4), prod) - 1
    【解决方案3】:

    一个选项:

        c(by(a, rep(1:(length(a)/4), each = 4), FUN = function(x) 
    
      (1 + x[1]) * (1 + x[2]) * (1 + x[3]) * (1 + x[4])-1
    
      )
    ))
    
            1         2 
    0.2578742 0.1800339 
    

    【讨论】:

      【解决方案4】:

      1) ts 这些实际上是为了表示时间序列,因此使用时间序列表示是有意义的:

      aggregate(ts(1+a, freq = 4), 1, prod) - 1
      ## Time Series:
      ## Start = 1 
      ## End = 2 
      ## Frequency = 1 
      [1] 0.2578742 0.1800339
      

      如果知道系列开始的年份,我们也可以使用start= 参数,例如

      aggregate(ts(1+a, freq = 4, start = 2000), 1, prod) - 1
      

      2) rollapply 这需要每 4 个值的乘积每次向前跳 4(而不是滑动窗口向前移动 1)。

      library(zoo)
      rollapply(1 + a, 4, by = 4, prod) - 1
      ## [1] 0.2578742 0.1800339
      

      3) aggregate.zoo 假设我们有一个yeaqqtr 向量yq,它给出了每个点的年份和季度。 yearqtr 呈现如下所示,内部表示为年份 + 分数,其中 Q1、Q2、Q3 和 Q4 的分数为 0、1/4、2/4 和 3/4。鉴于我们可以对其进行聚合:

      library(zoo)
      
      yq <- as.yearqtr(2000) + 0:7/4
      yq
      ## [1] "2000 Q1" "2000 Q2" "2000 Q3" "2000 Q4" "2001 Q1" "2001 Q2" "2001 Q3"
      ## [8] "2001 Q4"
      
      aggregate(zoo(1 + a), as.integer(yq), prod) - 1
      ##      2000      2001 
      ## 0.2578742 0.1800339
      

      3a) 使用相同的yq 我们可以tapply 超过1+a

      library(zoo)
      
      tapply(1 + a, as.integer(yq), prod) - 1
      ##      2000      2001 
      ## 0.2578742 0.1800339 
      

      【讨论】:

        【解决方案5】:

        基于 R 的想法,

        sapply(split(a, rep(c(FALSE, TRUE), each = length(a) / 2)), 
                     function(i)((1 + i[1]) * (1 + i[2]) * (1 + i[3]) * (1 + i[4])) - 1)
        
        #    FALSE      TRUE 
        #0.2578742 0.1800339
        

        【讨论】:

          猜你喜欢
          • 2013-08-28
          • 1970-01-01
          • 2012-12-21
          • 2022-11-02
          • 2013-10-13
          • 2017-05-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多