Nick
Nick

Reputation: 247

Loop for Correlation in R

I trying to find a way to do a nested for loop in r to get every possible correlation combination of this:

cor(y, column1* column2), cor(y, column1* column3), cor(y, column1* column4)
and so on

This is what I have tried so far:

for(i in 1:length(dataframe))
{
for(j in 1:length(dataframe))
{
joint_correlation(i,j)=cor(y ~ dataframe(i) * dataframe(j));
}
}

My dataframe has 115 columns like shown with a small sample:

FG_pct FGA FT FT_pct FTA GP GS GmSc  MP    ORB

0.625   8   0  0.00   0  1  0   6.6  28.4   2   
0.500   4   0  0.00   1  2  0   2.1  17.5   0   
0.000   1   0  0.00   0  3  0   1.2  6.6    1   
0.500   6   0  0.00   0  4  0   3.6  13.7   1   
0.500   2   0  0.00   0  5  0   0.9  7.4    1   

I want to find the correlation for cor(MP, column1* column2) for every possible combination switched out for column1 and column2. This way, I wouldn't have to do every single one of them separately. If possible, I would like to save the output for each correlation combination cor(MP, column1* column2), cor(MP, column1* column3),cor(MP, column2* column4), etc. in a separate column.

This is an example of what I want: cor(MP, FG_pct*FT_pct)

Upvotes: 0

Views: 490

Answers (2)

Nick
Nick

Reputation: 247

Assuming you want the correlations of every column multiplied by combinations of two of the remaining columns.

We can find the names of according combinations using combn(names(dat), 2) which we put into an lapply.

combs <- do.call(cbind.data.frame,
                 lapply("MP", rbind, combn(names(dat)[names(dat) != "MP"], 2)))
combs
#        1      2   3
# 1     MP     MP  MP
# 2 FG_pct FG_pct FGA
# 3    FGA     FT  FT

In another lapply we subset the data on the name-combinations and calculate cor with formula cor(x1 ~ x2 * x3). Simultaneously we store the names pasted as formula in an attribute, to remember later what we've calculated in each iteration.

res.l <- lapply(combs, function(x) {
  `attr<-`(cor(dat[,x[1]], dat[,x[2]]*dat[,x[3]]),
           "what", {
             paste0(x[1], ", ", paste(x[2], "*", x[3]))})
})

Finally we unlist and setNames according to the attributes.

res <- setNames(unlist(res.l), sapply(res.l, attr, "what"))
res

Result

# MP, FG_pct * FGA  MP, FG_pct * FT     MP, FGA * FT 
#        0.2121374        0.2829003        0.4737892 

Check:

(Note, that you can directly put the names, e.g. MP, FG_pct * FGA into the cor function.)

with(dat, cor(MP, FG_pct * FGA))
# [1] 0.2121374
with(dat, cor(MP, FG_pct * FT))
# [1] 0.2829003
with(dat, cor(MP, FGA * FT))
# [1] 0.4737892

To sort, use e.g. sort(res) or rev(sort(res)).

Toy data:

set.seed(42)
dat <- as.data.frame(`colnames<-`(MASS::mvrnorm(n=1e4, 
                          mu=c(0.425, 4.2, 0.2, 3), 
                          Sigma=matrix(c(1, .3, .7, 0,
                                         .3, 1, .5, 0,
                                         .7, .5, 1, 0,
                                         0, 0, 0, 1), nrow=4), 
                          empirical=T), c("FG_pct", "MP", "FGA", "FT")))

Upvotes: 0

brendbech
brendbech

Reputation: 419

Edit: Jean-Claude Arbaut gives a better answers, as commented to this answer. Use cor(df).

Here is my botched answer: Using the library corrgram (Which is mainly a visual tool) we can easily get all combinations of correlations in a dataset. Example:

library(corrgram)

#Example data

df <- data.frame(x = rnorm(50, 5, 5),
               y = rnorm(50, 2, 5))

df$z <- df$x / df$y
df$abc <- df$x * df$y * df$z

#panel arguments are necessary if you want to visualize correlations
corr <- corrgram(df,
         order = F, 
         lower.panel = panel.cor,
         upper.panel = panel.pts,
         text.panel = panel.txt,
         diag.panel = panel.minmax,
         main = "Correlation")

#call corr gives
corr

             x          y         z        abc
x   1.00000000 0.07064179 0.1402051 0.89166002
y   0.07064179 1.00000000 0.2495239 0.08024278
z   0.14020508 0.24952388 1.0000000 0.14649093
abc 0.89166002 0.08024278 0.1464909 1.00000000

There is absolutely a better way for doing this with functions and without a package, but its early here, and if you are desperate to get the results this will probably do you fine.

p.s using the corrgram() function without assigning it will give you a nice visualization of your correlations.

Upvotes: 2

Related Questions