Encontrando pares de variáveis com correlação maior que um valor

Olá, gostaria de saber quais pares de variáveis de uma base têm correlação maior que 0.6. Como poderia fazer isso no R.

Por exemplo, como retornar as colunas com correlação maior que 0.6 a partir da matriz abaixo.

cor(mtcars)
#>             mpg        cyl       disp         hp        drat         wt
#> mpg   1.0000000 -0.8521620 -0.8475514 -0.7761684  0.68117191 -0.8676594
#> cyl  -0.8521620  1.0000000  0.9020329  0.8324475 -0.69993811  0.7824958
#> disp -0.8475514  0.9020329  1.0000000  0.7909486 -0.71021393  0.8879799
#> hp   -0.7761684  0.8324475  0.7909486  1.0000000 -0.44875912  0.6587479
#> drat  0.6811719 -0.6999381 -0.7102139 -0.4487591  1.00000000 -0.7124406
#> wt   -0.8676594  0.7824958  0.8879799  0.6587479 -0.71244065  1.0000000
#> qsec  0.4186840 -0.5912421 -0.4336979 -0.7082234  0.09120476 -0.1747159
#> vs    0.6640389 -0.8108118 -0.7104159 -0.7230967  0.44027846 -0.5549157
#> am    0.5998324 -0.5226070 -0.5912270 -0.2432043  0.71271113 -0.6924953
#> gear  0.4802848 -0.4926866 -0.5555692 -0.1257043  0.69961013 -0.5832870
#> carb -0.5509251  0.5269883  0.3949769  0.7498125 -0.09078980  0.4276059
#>             qsec         vs          am       gear        carb
#> mpg   0.41868403  0.6640389  0.59983243  0.4802848 -0.55092507
#> cyl  -0.59124207 -0.8108118 -0.52260705 -0.4926866  0.52698829
#> disp -0.43369788 -0.7104159 -0.59122704 -0.5555692  0.39497686
#> hp   -0.70822339 -0.7230967 -0.24320426 -0.1257043  0.74981247
#> drat  0.09120476  0.4402785  0.71271113  0.6996101 -0.09078980
#> wt   -0.17471588 -0.5549157 -0.69249526 -0.5832870  0.42760594
#> qsec  1.00000000  0.7445354 -0.22986086 -0.2126822 -0.65624923
#> vs    0.74453544  1.0000000  0.16834512  0.2060233 -0.56960714
#> am   -0.22986086  0.1683451  1.00000000  0.7940588  0.05753435
#> gear -0.21268223  0.2060233  0.79405876  1.0000000  0.27407284
#> carb -0.65624923 -0.5696071  0.05753435  0.2740728  1.00000000

Created on 2020-10-08 by the reprex package (v0.3.0)

2 curtidas

wamorim,

Olha, o código ficou meio gambiarra, mas acho que funciona:

library(magrittr)

cols <- mtcars %>%
  base::names() %>%
  purrr::cross2(., ., `==`) %>%
  purrr::map(stringr::str_c, collapse = "_") %>%
  purrr::flatten_chr()

mtcars %>%
  base::as.list() %>%
  purrr::cross2(., ., ~all(.x == .y)) %>%
  purrr::set_names(cols) %>%
  purrr::map(~cor(.x[[1]], .x[[2]])) %>%
  purrr::keep(~.x > 0.6) %>%
  names()
#>  [1] "drat_mpg"  "vs_mpg"    "disp_cyl"  "hp_cyl"    "wt_cyl"    "cyl_disp" 
#>  [7] "hp_disp"   "wt_disp"   "cyl_hp"    "disp_hp"   "wt_hp"     "carb_hp"  
#> [13] "mpg_drat"  "am_drat"   "gear_drat" "cyl_wt"    "disp_wt"   "hp_wt"    
#> [19] "vs_qsec"   "mpg_vs"    "qsec_vs"   "drat_am"   "gear_am"   "drat_gear"
#> [25] "am_gear"   "hp_carb"

Created on 2020-10-09 by the reprex package (v0.3.0)

1 curtida

Valeu, Caio! Também fiz um jeito usando R base aqui:

# Matriz de correlação
matriz <- cor(mtcars)

# Nomes das colunas da base mtcars
nomes <- names(mtcars)

# Cria um vetor vazio para salvarmos os resultados
resultado <- c()

for(nome in nomes) {
  # Pega uma das variáveis da matriz
  valores <- matriz[ , nome]
  
  # Avalia quais outras variáveis tem correlação maior 
  # que 6 com a coluna selecionada
  variaveis <- matriz[valores > 0.6, nome]
  
  # modifica o nome para formar os pares de variáveis
  names(variaveis) <- paste(nome, names(variaveis))
  
  # Salva o resultado da de cada iteração no objeto "resultado"
  resultado <- c(resultado, variaveis)
}

resultado
#>   mpg mpg  mpg drat    mpg vs   cyl cyl  cyl disp    cyl hp    cyl wt  disp cyl 
#> 1.0000000 0.6811719 0.6640389 1.0000000 0.9020329 0.8324475 0.7824958 0.9020329 
#> disp disp   disp hp   disp wt    hp cyl   hp disp     hp hp     hp wt   hp carb 
#> 1.0000000 0.7909486 0.8879799 0.8324475 0.7909486 1.0000000 0.6587479 0.7498125 
#>  drat mpg drat drat   drat am drat gear    wt cyl   wt disp     wt hp     wt wt 
#> 0.6811719 1.0000000 0.7127111 0.6996101 0.7824958 0.8879799 0.6587479 1.0000000 
#> qsec qsec   qsec vs    vs mpg   vs qsec     vs vs   am drat     am am   am gear 
#> 1.0000000 0.7445354 0.6640389 0.7445354 1.0000000 0.7127111 1.0000000 0.7940588 
#> gear drat   gear am gear gear   carb hp carb carb 
#> 0.6996101 0.7940588 1.0000000 0.7498125 1.0000000

Created on 2020-10-09 by the reprex package (v0.3.0)

1 curtida

mais 3 jeitos:

library(tidyverse)

library(correlation)
correlation(mtcars) %>%
    filter(abs(r) > 0.6)
#> Parameter1 | Parameter2 |     r |         95% CI |     t | df |      p |  Method | n_Obs
#> ----------------------------------------------------------------------------------------
#> mpg        |        cyl | -0.85 | [-0.93, -0.72] | -8.92 | 30 | < .001 | Pearson |    32
#> mpg        |       disp | -0.85 | [-0.92, -0.71] | -8.75 | 30 | < .001 | Pearson |    32
#> mpg        |         hp | -0.78 | [-0.89, -0.59] | -6.74 | 30 | < .001 | Pearson |    32

library(corrr)
correlate(mtcars) %>% 
    stretch(remove.dups = TRUE) %>%
    filter(abs(r) > 0.6)
#> # A tibble: 26 x 3
#>    x     y          r
#>    <chr> <chr>  <dbl>
#>  1 mpg   cyl   -0.852
#>  2 mpg   disp  -0.848
#>  3 mpg   hp    -0.776
#> # … with 16 more rows

library(widyr)
mtcars %>%
    rownames_to_column() %>%
    pivot_longer(-rowname) %>%
    pairwise_cor(name, rowname, value) %>%
    filter(abs(correlation) > 0.6) %>%
    rowwise() %>%
    mutate(par = paste0(sort(c(item1, item2)), collapse = "")) %>%
    distinct(par, .keep_all = TRUE) %>%
    select(-par)
#> # A tibble: 26 x 3
#>    item1 item2 correlation
#>    <chr> <chr>       <dbl>
#>  1 cyl   mpg        -0.852
#>  2 disp  mpg        -0.848
#>  3 hp    mpg        -0.776
#> # … with 16 more rows

Created on 2020-10-09 by the reprex package (v0.3.0)

2 curtidas

OI Athos, blz?

no 3º jeito, o pairwise_cor testa a correlação entre cada item da variável? É isso?

Cara, é isso mesmo. Ele recebe o ID da pessoa e tbm a coluna com as categorias que vc quer fazer o pairwise corr. Ou seja, diferente dos outros jeitos que usam um conjunto de colunas, o pairwise_cor() pensa no formato “derretido”, tipico de um pivot_longer().