Reputation: 98
I have a dataframe with 5 variables. These data are for several years and I have grouped them season wise. I want to compute the cross correlation and lag correlation among the 5 variables for every season. How can I do this using acf function in R? I found some examples but they are giving the correlations only between two variables using the 'cor' function or 'lag' function. Since I have 5 variables, I can use acf function which can give cross and lag correlations among all the variables, but I don't know how to use it with the group_by in dplyr package. I think there must be elegant way to do this in R. The dataframe looks like:
Season Res1 Res2 Res3 Res4 Res5
summer 4.4336 4.8965 31.4385 -0.6288 -1.1579
summer 2.5130 3.7541 -2.2947 12.4083 -0.6241
. . . . . .
. . . . . .
For example, I can compute the correlations using acf for the whole data. If I take the 5 variables as matrix Resdf then I can do it like this:
M<-acf(Resdf,lag.max =1,type ="correlation",plot=TRUE)
This will give me the cross correlation and lag-1 correlations among the 5 variables. I can extract the cross correlations as M0<-M$acf[1,,]
and lag-1 correlations as M1<-M$acf[2,,]
which will give the 5x5 matrices like this:
>M0
[,1] [,2] [,3] [,4] [,5]
[1,] 1.0000000 0.8606853 0.0500022 -0.3440501 -0.1709415
[2,] 0.8606853 1.0000000 0.2662694 -0.5228191 -0.2376250
[3,] 0.0500022 0.2662694 1.0000000 -0.5710574 -0.2005080
[4,] -0.3440501 -0.5228191 -0.5710574 1.0000000 0.2163159
[5,] -0.1709415 -0.2376250 -0.2005080 0.2163159 1.0000000
and lag-1 correlations as
> M1
[,1] [,2] [,3] [,4] [,5]
[1,] 0.72688806 0.7648605807 0.2416748 -0.4725366 -0.24970773
[2,] 0.66442943 0.7413684874 0.3125458 -0.4918965 -0.25046233
[3,] -0.06882386 0.0002300747 0.2523668 -0.1015463 -0.01341474
[4,] -0.13060710 -0.2369795768 -0.3061068 0.4032776 0.12751785
[5,] -0.10527689 -0.1044584694 -0.1070397 0.1025203 0.33448922
Is there any way I can use acf in this way to get the correlation matrices for the 4 seasons?
Upvotes: 0
Views: 1903
Reputation: 13591
Example data following your format:
set.seed(1)
df <- data.frame(Season=c(rep("spring",3),rep("summer",3)),
Res1=rnorm(6))
df1 <- df %>% mutate(Res2=Res1+(rnorm(6)*0.1),
Res3=Res1+(rnorm(6)*0.2),
Res4=Res1+(rnorm(6)*0.3),
Res5=Res1+(rnorm(6)*0.4))
Use tidyverse
nest
to perform 'complex' operations on a grouped data frame. I perform acf
in the first mutate...map
, and then extract acf[1,,]
and acf[2,,]
and convert to data frame in the second mutate...map
:
library(tidyverse)
df2 <- df1 %>%
group_by(Season) %>%
nest() %>%
mutate(data = map(data, ~acf(., lag.max=1, type="correlation", plot=F))) %>%
mutate(data = map(data, ~as.data.frame(rbind(.x$acf[1,,], .x$acf[2,,])))) %>%
unnest(data)
The first 10 lines of output:
Season V1 V2 V3 V4 V5
1 spring 1.000000e+00 0.999926654 0.888928901 0.999945732 0.9501684141
2 spring 9.999267e-01 1.000000000 0.894411297 0.999998566 0.9463231324
3 spring 8.889289e-01 0.894411297 1.000000000 0.893652539 0.7018425064
4 spring 9.999457e-01 0.999998566 0.893652539 1.000000000 0.9468691987
5 spring 9.501684e-01 0.946323132 0.701842506 0.946869199 1.0000000000
6 spring -6.415051e-01 -0.649989355 -0.892898812 -0.648808668 -0.3899507753
7 spring -6.360042e-01 -0.644491958 -0.888124854 -0.643310737 -0.3846451323
8 spring -3.639938e-01 -0.371690371 -0.615653299 -0.370617371 -0.1470652339
9 spring -6.367791e-01 -0.645266390 -0.888800271 -0.644085234 -0.3853904576
10 spring -7.499137e-01 -0.757869871 -0.969595555 -0.756763981 -0.5063447715
summer
follows in the full data frame. The first 5 rows
of each season
contain acf[1,,]
and the following 5 rows
contain acf[2,,]
Upvotes: 2