How to apply a function to every consecutive n elements in a vector

后端 未结 5 536
难免孤独
难免孤独 2021-01-22 09:48

I am trying to convert quarterly returns to yearly returns. Given a vector of quarterly returns, how can this be done?

I am fairly new to R-programming, so I haven\'t r

相关标签:
5条回答
  • 2021-01-22 10:21

    An idea via base 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
    
    0 讨论(0)
  • 2021-01-22 10:33

    An option:

        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 
    
    0 讨论(0)
  • As they are quarterly returns divide the vector into groups of 4 and calculate for each group.

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

    The grouping part and calculation part can be done in variety of ways. For example, the above can also be done using split + sapply

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

    Or grouping can also be done using rep

    tapply(a,rep(seq_along(a), each = 4, length.out = length(a)), 
             function(x) prod(1 + x) - 1)
    
    0 讨论(0)
  • 2021-01-22 10:42

    1) ts These are really intended to represent time series so it makes sense to use a time series representation:

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

    We could also use the start= argument if knew the year that the series starts, e.g.

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

    2) rollapply This takes the product of every 4 values skipping ahead 4 each time (instead of a sliding window moving ahead by 1).

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

    3) aggregate.zoo Suppose we have a yeaqqtr vector yq that gives the year and quarter of each point. yearqtr renders as shown below and internally is represented as year + fraction where the fraction is 0, 1/4, 2/4 and 3/4 for Q1, Q2, Q3 and Q4. Given that we can aggregate over it:

    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) Using the same yq we can tapply over 1+a :

    library(zoo)
    
    tapply(1 + a, as.integer(yq), prod) - 1
    ##      2000      2001 
    ## 0.2578742 0.1800339 
    
    0 讨论(0)
  • 2021-01-22 10:45

    Using apply:

    apply(matrix(a, nrow = 4), 2, function(x) prod(1 + x) - 1)
    #[1] 0.2578742 0.180033
    
    0 讨论(0)
提交回复
热议问题