web-dev-qa-db-fra.com

Calculer la corrélation - cor () - pour seulement un sous-ensemble de colonnes

J'ai une base de données et voudrais calculer le corrélation (avec Spearman, les données sont catégoriques et classées) mais seulement pour un sous-ensemble de colonnes. J'ai essayé avec tous, mais la fonction cor () de R n'accepte que les données numériques (x doit être numérique, indique le message d'erreur), même si Spearman est utilisé.

Une approche brutale consiste à supprimer les colonnes non numériques du cadre de données. Ce n'est pas aussi élégant, pour la vitesse, je ne veux toujours pas calculer les corrélations entre toutes les colonnes .

J'espère qu'il y a un moyen de simplement dire "calculer les corrélations pour les colonnes x, y, z". Les références de colonne peuvent être numérotées ou nommées. Je suppose que la manière flexible de les fournir serait par un vecteur.

Toutes les suggestions sont appréciées.

45
wishihadabettername

si vous avez un cadre de données où certaines colonnes sont numériques et d'autres (caractère ou facteur) et que vous souhaitez uniquement effectuer les corrélations des colonnes numériques, vous pouvez procéder comme suit:

set.seed(10)

x = as.data.frame(matrix(rnorm(100), ncol = 10))
x$L1 = letters[1:10]
x$L2 = letters[11:20]

cor(x)

Error in cor(x) : 'x' must be numeric

mais

cor(x[sapply(x, is.numeric)])

             V1         V2          V3          V4          V5          V6          V7
V1   1.00000000  0.3025766 -0.22473884 -0.72468776  0.18890578  0.14466161  0.05325308
V2   0.30257657  1.0000000 -0.27871430 -0.29075170  0.16095258  0.10538468 -0.15008158
V3  -0.22473884 -0.2787143  1.00000000 -0.22644156  0.07276013 -0.35725182 -0.05859479
V4  -0.72468776 -0.2907517 -0.22644156  1.00000000 -0.19305921  0.16948333 -0.01025698
V5   0.18890578  0.1609526  0.07276013 -0.19305921  1.00000000  0.07339531 -0.31837954
V6   0.14466161  0.1053847 -0.35725182  0.16948333  0.07339531  1.00000000  0.02514081
V7   0.05325308 -0.1500816 -0.05859479 -0.01025698 -0.31837954  0.02514081  1.00000000
V8   0.44705527  0.1698571  0.39970105 -0.42461411  0.63951574  0.23065830 -0.28967977
V9   0.21006372 -0.4418132 -0.18623823 -0.25272860  0.15921890  0.36182579 -0.18437981
V10  0.02326108  0.4618036 -0.25205899 -0.05117037  0.02408278  0.47630138 -0.38592733
              V8           V9         V10
V1   0.447055266  0.210063724  0.02326108
V2   0.169857120 -0.441813231  0.46180357
V3   0.399701054 -0.186238233 -0.25205899
V4  -0.424614107 -0.252728595 -0.05117037
V5   0.639515737  0.159218895  0.02408278
V6   0.230658298  0.361825786  0.47630138
V7  -0.289679766 -0.184379813 -0.38592733
V8   1.000000000  0.001023392  0.11436143
V9   0.001023392  1.000000000  0.15301699
V10  0.114361431  0.153016985  1.00000000
62
Greg

Pour les données numériques, vous avez la solution. Mais ce sont des données catégoriques, vous avez dit. Alors la vie devient un peu plus compliquée ...

Bien, premièrement: la quantité d'association entre deux variables catégorielles n'est pas mesurée avec une corrélation de rang de Spearman, mais avec un test du chi carré par exemple. Quelle est la logique en fait. Le classement signifie qu'il y a un peu d'ordre dans vos données. Maintenant, dites-moi ce qui est plus gros, jaune ou rouge? Je sais que parfois R effectue une corrélation de rang de spearman sur des données catégoriques. Si je code jaune 1 et rouge 2, R considérerait le rouge plus grand que le jaune.

Alors, oubliez Spearman pour les données catégoriques. Je vais démontrer le chisq-test et comment choisir des colonnes en utilisant combn (). Mais vous auriez intérêt à passer un peu plus de temps avec le livre d'Agresti: http://www.Amazon.com/Categorical-Analysis-Wiley-Probability-Statistics/dp/0471360937

set.seed(1234)
X <- rep(c("A","B"),20)
Y <- sample(c("C","D"),40,replace=T)

table(X,Y)
chisq.test(table(X,Y),correct=F)
# I don't use Yates continuity correction

#Let's make a matrix with tons of columns

Data <- as.data.frame(
          matrix(
            sample(letters[1:3],2000,replace=T),
            ncol=25
          )
        )

# You want to select which columns to use
columns <- c(3,7,11,24)
vars <- names(Data)[columns]

# say you need to know which ones are associated with each other.
out <-  apply( combn(columns,2),2,function(x){
          chisq.test(table(Data[,x[1]],Data[,x[2]]),correct=F)$p.value
        })

out <- cbind(as.data.frame(t(combn(vars,2))),out)

Ensuite, vous devriez obtenir:

> out
   V1  V2       out
1  V3  V7 0.8116733
2  V3 V11 0.1096903
3  V3 V24 0.1653670
4  V7 V11 0.3629871
5  V7 V24 0.4947797
6 V11 V24 0.7259321

Où V1 et V2 indiquent entre quelles variables il va, et "out" donne la valeur p pour l'association. Ici toutes les variables sont indépendantes. Ce à quoi vous vous attendriez, car j'ai créé les données au hasard.

15
Joris Meys

J'ai trouvé un moyen plus simple en consultant le script R généré par Rattle. Cela ressemble à ci-dessous:

correlations <- cor(mydata[,c(1,3,5:87,89:90,94:98)], use="pairwise", method="spearman")
2
wishihadabettername

Une autre option consisterait simplement à utiliser l'excellent paquet corrrhttps://github.com/drsimonj/corrr et à

require(corrr)
require(dplyr)

myData %>% 
   select(x,y,z) %>%  # or do negative or range selections here
   correlate() %>%
   rearrange() %>%  # rearrange by correlations
   shave() # Shave off the upper triangle for a cleaner result

Les étapes 3 et 4 sont entièrement facultatives et sont simplement incluses pour démontrer l'utilité du package.

0
Holger Brandl