有没有办法做一个嵌套的 for 循环来获得 R 中的所有相关性?

Is there a way to do a nested for loop to get all correlations in R?

我试图找到一种方法在 r 中做一个嵌套的 for 循环,以获得每一个可能的相关组合:

cor(y, column1 * column2), cor(y, column1 * column3), cor(y, column1 * column4), cor(y, column2 * column3)

或者在我的例子中:

cor(MP, FG_pct * FGA), cor(MP, FG_pct * FT), cor(MP, FG_pct * FT_pct)
等等

这是我目前尝试过的方法:

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

我的数据框有 115 列,如小样本所示:

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   

我想为 column1 和 column2 切换出的每个可能组合找到 cor(MP, column1 * column2) 的相关性。这样,我就不必分别完成每一个。我相信遍历所有场景的循环是最好的方法。如果可能的话,我想将每个相关组合 cor(MP, FG_pct * FGA)cor(MP, FG_pct * FT_pct)cor(MP, GmSc * ORB) 等的输出保存在单独的列中。

编辑

sessionInfo()

    R version 3.6.1 (2019-07-05)
    Platform: x86_64-apple-darwin15.6.0 (64-bit)
    Running under: macOS Catalina 10.15.4

    Matrix products: default
    BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
    LAPACK: /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRlapack.dylib

    Random number generation:
    RNG:     Mersenne-Twister 
    Normal:  Inversion 
    Sample:  Rounding 

    locale:
    [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

    attached base packages:
    [1] stats     graphics  grDevices utils     datasets  methods   base     

    other attached packages:
    [1] dplyr_0.8.5        magrittr_1.5       ggplot2_3.3.0      corrr_0.4.2        RColorBrewer_1.1-2
    [6] readr_1.3.1        corrplot_0.84     

    loaded via a namespace (and not attached):

[1] Rcpp_1.0.4       rstudioapi_0.11  knitr_1.24       MASS_7.3-51.5    hms_0.5.3        tidyselect_1.0.0
[7] munsell_0.5.0    colorspace_1.4-1 R6_2.4.1         rlang_0.4.5      tools_3.6.1      grid_3.6.1      
[13] gtable_0.3.0     xfun_0.9         withr_2.1.2      assertthat_0.2.1 tibble_2.1.3     lifecycle_0.2.0 
[19] crayon_1.3.4     farver_2.0.3     purrr_0.3.3      vctrs_0.2.4      glue_1.3.2       compiler_3.6.1  
[25] pillar_1.4.3     scales_1.1.0     pkgconfig_2.0.3'

将所有组合存储在一个矩阵中:

x <- t(combn(115, 2))

每行有两个列号(首先用您的计算创建一个矩阵以使事情更简单)。您可以使用循环或 sapply。这是一个小例子:

set.seed(42)
dta <- cor(cbind(A=rnorm(15), B=rnorm(15), C=rnorm(15), D=rnorm(15)))
x <- t(combn(4, 2))
cors <- sapply(1:6, function(i) cor(dta[, x[i, ]])[1,2])
cor.lbl <- sapply(1:6, function(i) paste(colnames(dta)[x[i, ]], collapse="-"))
names(cors) <- cor.lbl
cors
#         A-B         A-C         A-D         B-C         B-D         C-D 
#  0.08735187 -0.77672266  0.10113427 -0.60521291 -0.45853048 -0.11072996 

假设您希望将每一列的相关性乘以其余两列的组合。

我们可以使用 combn(names(dat), 2) 找到相应组合的名称,我们将其放入 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

在另一个 lapply 中,我们对名称组合的数据进行子集化,并使用公式 cor(x1 ~ x2 * x3 计算 cor。同时,我们将名称 pasted 作为公式存储在 attribute 中,以便稍后记住我们在每次迭代中计算的内容。

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]))})
})

最后我们根据属性unlistsetNames

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

结果

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

检查:

(注意,您可以直接将名称,例如 MP, FG_pct * FGA 放入 cor 函数中。)

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

要排序,请使用例如sort(res)rev(sort(res)).


玩具数据:

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")))