rcorrelationrolling-computationrollapply

Calculate rolling correlation for all permutations of columns in a DF


I have a table that contains 4 numeric vectors, I would like to calculate and populate a new table that shows the rolling correlation of each possible column pair.

I want to transform this simple table:

Column A Column B Column c Column d
1 8 3 4
7 5 5 7

Into a table that looks like this with vectors of rolling correlation.

AB AC AD BC BD CD

I tried the rollapply function and more or less every related question in the search bar and have not been able to resolve the problem.


Solution

  • This solution is based on this comment by @GGrothendieck, plus combn() to generate the new column names.

    library(zoo)
    
    # example data
    set.seed(13)
    dat <- data.frame(
      A = rnorm(20),
      B = rnorm(20),
      C = rnorm(20),
      D = rnorm(20)
    )
    
    pairnames <- names(dat) |>
      combn(2, \(x) paste(x, collapse = ""))
    
    dat |>
      rollapply(10, \(x) cor(x)[lower.tri(cor(x))], by.column = FALSE) |>
      as.data.frame() |>
      setNames(pairnames)
    
                  AB          AC          AD          BC          BD          CD
    1   0.0003534898 -0.13612373 -0.22849979  0.45029555 -0.11457305 -0.26487479
    2  -0.0580758074 -0.12874149  0.06382879  0.46018347 -0.07621848 -0.29229352
    3   0.1551727794 -0.01388046  0.10599110  0.32994185 -0.19459186 -0.37626526
    4  -0.0264603584 -0.02640355  0.21575705  0.29424980 -0.19790990 -0.35080532
    5  -0.0067446215  0.04424283  0.48912209  0.47819290 -0.21369265 -0.11972016
    6  -0.1970381395  0.06705549  0.37975883  0.57596940 -0.44240169 -0.06895075
    7  -0.2725443707  0.11127621  0.42059540  0.67974874 -0.38430076 -0.09602750
    8  -0.0434380298  0.12698397  0.67938827  0.58240537 -0.32976570 -0.26464101
    9   0.1026328910  0.34521756  0.66884148  0.16218774 -0.09503962 -0.02151401
    10  0.0717026253  0.31339628  0.75363354 -0.03758187  0.04365913  0.09453714
    11  0.0861075966  0.19405089  0.83701868  0.03339110 -0.03997420  0.14340951