Search code examples
rdataframeapply

R: rolling ratio of values in each colunm


I'm looking to get the rolling ratio of values in each column. e.g. 5th/1st, 6th/2nd etc and have the results in a new data frame.

df <- data.frame(Group = rep(c('A', 'B', 'C', 'D'), each = 4),
                 score_1 = 1:16,
                 score_2 = 5:20)        

With the example data above I want each row (n) (from the 5th down) to be divided by n-4, in this case would create the below table of results.

5.0  1.8
3.0  1.7
2.3  1.6
2.0  1.5
1.8  1.4
1.7  1.4
1.6  1.4
1.5  1.3
1.4  1.3
1.4  1.3
1.4  1.3
1.3  1.3

Solution

  • You can use head() and tail():

    tail(df, -4)[-1] / head(df, -4)[-1]
    
    # Also
    # (\(x, n) tail(x, n) / head(x, n))(df[-1], -4)
    #
    #     score_1  score_2
    # 5  5.000000 1.800000
    # 6  3.000000 1.666667
    # 7  2.333333 1.571429
    # 8  2.000000 1.500000
    # 9  1.800000 1.444444
    # 10 1.666667 1.400000
    # 11 1.571429 1.363636
    # 12 1.500000 1.333333
    # 13 1.444444 1.307692
    # 14 1.400000 1.285714
    # 15 1.363636 1.266667
    # 16 1.333333 1.250000
    

    With dplyr, you can use lag():

    library(dplyr)
    
    df %>%
      mutate(across(-Group, ~ .x / lag(.x, 4L)))